C# 手动复位事件不工作;线
我有一个创建线程的客户端 该线程有一个C# 手动复位事件不工作;线,c#,multithreading,wcf,manualresetevent,C#,Multithreading,Wcf,Manualresetevent,我有一个创建线程的客户端 该线程有一个WaitOne(),因此,当它卡在那里时,我的客户端不会死掉。 但是,当我想关闭客户端时,我需要对手动重置事件执行Set() 我在主类中声明手动重置事件: public ManualResetEvent mreIn = new ManualResetEvent(false); 这是我的Connect函数,它使用start函数创建线程: public void Connect() { objClientThread = new
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();
}
}
因此,这种方法的工作原理是。。。
所有模块都在WaitOne()上初始化和阻止
当我关闭一个模块时,回调函数执行Set()
,但是WaitOne()
没有解锁,线程也不会继续。
我遗漏了什么?看起来您使用ManualResetEvent的方式是正确的。但是,您的线程是背景。如果所有其他非后台线程都退出,那么您的线程将在随机位置中止,并且mreIn.WaitOne()之后的代码可能不会执行
如果是这样的话,那么将您的therad设置为非后台将解决问题。问题是,当我创建服务客户端时,我必须传递回调的instance上下文,并且我正在执行一个新的操作,因此我没有将当前的实例上下文放入,而回调正在对其他实例执行,因此,我所做的每一个价值观或事件的变化都没有反映在当前的价值观中。
感谢@Henkholtman的帮助:)请注意以下示例:
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();
}
}
第一个检查:回调是否在同一个实例上运行?是的,回调运行同一个实例。客户端是使用executeAssembly执行的.exe
。此.exe
具有客户端类的实例。当exe
启动时,调用Connect()
函数,创建线程,但您的objProxy看起来像一个命名错误的主机。objProxy被配置为访问端点并具有配置,以便netNamedPipes可以找到服务器。与此无关我做了更多的测试,看起来回调中执行的任何操作都不会执行,就像其他对象一样。如何确保回调是在同一对象上执行的?此后台线程使用eventhandler控制其他线程。另一条线肯定没有死,100%肯定
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();
}
}