我有一个客户端来创建一个线程。
这个线程有一个WaitOne(),所以当它被卡在那里时,我的客户端不会死。但是当我想关闭我的客户时,我需要在手动重置事件上做一个Set()。
我在主类中声明手动重置事件:
public ManualResetEvent mreIn = new ManualResetEvent(false);这是我的Connect函数,它使用start函数创建线程:
public void Connect()
{
objClientThread = new Thread(start) { IsBackground = true };
objClientThread.Start();
}
/// <summary>
/// Starts the client program.
/// </summary>
private void start()
{
//We Open the proxy to let connections happen
objProxy.Open();
if (performHandshake())
{
IsConnected = true;
DelayedShutdownBool = false;
//While connected, the thread keeps the client alive
mreIn.WaitOne();
if (OnShutdownInitiated != null)
{
OnShutdownInitiated(this, new EventArgs());
}
System.Threading.Thread.Sleep(500);
objProxy.Close();
objConfiguration = null;
IsConnected = false;
mreOut.Set();
}
}我有一个回调,它做Set()
Boolean IServiceCallbackContract.Shutdown()
{
mreIn.Set();
return true;
}所以这工作的方式是..。当我关闭一个模块时,所有模块都在WaitOne()上初始化和阻塞,回调执行Set(),但是WaitOne()没有被解锁,线程也没有继续。我遗漏了什么?
发布于 2013-08-19 13:47:05
问题是,当我创建服务客户端时,我必须传递回调的instace上下文,并且我正在执行一个new,所以我没有将current实例上下文和回调执行到其他实例,因此我所做的值或事件的每一次更改都没有反映在当前的意图中。谢谢您的帮助:)
发布于 2013-08-16 15:56:49
看来您使用ManualResetEvent的方式是正确的。但是你的线索是背景。如果所有其他非后台线程退出,那么您的线程将在一个随机位置中止,mreIn.WaitOne()之后的代码可能不会执行。
如果是这样的话,那么让你的非背景解决这个问题。
发布于 2019-03-05 06:20:31
请注意这个例子:
class ThreadManager : IThreadManager
{
private System.Threading.ManualResetEvent _Mre;
private static CancellationTokenSource _CancellationToken;
private int _ThreadCount;
public ThreadManager(int threadCount)
{
_Mre = new System.Threading.ManualResetEvent(true);
_CancellationToken = new CancellationTokenSource();
_ThreadCount = threadCount;
}
public void DoWork(Action action)
{
_Mre.WaitOne();
Task.Factory.StartNew(action, _CancellationToken.Token);
}
public void Stop()
{
_CancellationToken.Cancel();
}
public void Resume()
{
_Mre.Set();
}
public void Waite()
{
_Mre.Reset();
}
}https://stackoverflow.com/questions/18277363
复制相似问题