Question

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?

Was it helpful?

Solution

The problem was that when I create the service client, I had to pass the instace context of the callbacks, and I was doing a new so I wasn't putting the current instance context and the callback was being done to other instance, so every change in values or event that I was doing was not reflected in the current intance. Thanks @HenkHolterman for the help :)

OTHER TIPS

Looks like you are using ManualResetEvent the right way. But, your thread is background. If all other non-background threads exit, then your thread would be aborted in a random place, and code after mreIn.WaitOne() may not execute.

If that is the case, then making your therad non-background would fix the issue.

please attention this example:

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();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top