0

I have a client which creates a thread.

That thread has a WaitOne() so while it is stuck there my client does not die. But when I want to shut down my client, I need to do a Set() on that manual reset event.

I declare the manual reset event in the main class:

public ManualResetEvent mreIn = new ManualResetEvent(false);

This is my Connect function which creates the thread with the start function:

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

And I have a callback which does the Set():

    Boolean IServiceCallbackContract.Shutdown()
    {
        mreIn.Set();
        return true;
    }

So the way this works is... all modules are initialized and blocked on the WaitOne() When I shutdown a module, the callback does the Set() but the WaitOne() is not unlocked and the thread does not continue. What am I missing?

4

3 回答 3

2

问题是,当我创建服务客户端时,我必须传递回调的实例上下文,而我正在这样做,new所以我没有将current实例上下文和回调执行到其他实例,所以每次更改我正在做的价值观或事件没有反映在当前的实例中。感谢@HenkHolterman 的帮助:)

于 2013-08-19T13:47:05.397 回答
0

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

如果是这种情况,那么让您的 therad 非背景将解决问题。

于 2013-08-16T15:56:49.180 回答
0

请注意这个例子:

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();
    }
}
于 2019-03-05T06:20:31.730 回答