ManualResetEvent不起作用;线

本文关键字:不起作用 ManualResetEvent | 更新日期: 2023-09-27 18:27:55

我有一个创建线程的客户端。

那个线程有一个WaitOne(),所以当它被卡住时,我的客户端不会死。但是,当我想关闭我的客户端时,我需要对手动重置事件执行Set()

我在主类中声明手动重置事件:

public ManualResetEvent mreIn = new ManualResetEvent(false);

这是我的Connect函数,它创建了带有启动函数的线程:

    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()不会解锁,线程也不会继续。我错过了什么?

ManualResetEvent不起作用;线

问题是,当我创建服务客户端时,我必须传递回调的instance上下文,并且我正在执行new,所以我没有放置current实例上下文,并且正在对其他实例执行回调,所以我正在执行的值或事件的每一次更改都没有反映在当前实例中。感谢@HenkHolterman的帮助:)

看起来您使用ManualResetEvent的方式是正确的。但是,你的线索是背景。如果所有其他非后台线程都退出,那么您的线程将在随机位置中止,并且mreIn.WaitOne()之后的代码可能不会执行。

如果是这样的话,那么让你的治疗没有背景就可以解决这个问题。

请注意这个例子:

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();
    }
}