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?

H H
  • 263,252
  • 30
  • 330
  • 514
AAlferez
  • 1,480
  • 1
  • 22
  • 48
  • First check: does the callback run on the same instance? – H H Aug 16 '13 at 15:55
  • Yes it does, the callback runs the same instance.The client is a `.exe` executed with executeAssembly. This `.exe` has an instance of the client class. When the `exe` starts, the `Connect()` function is called, creating the thread – AAlferez Aug 16 '13 at 16:19
  • But your objProxy looks like a mis-named Host. – H H Aug 16 '13 at 17:15
  • objProxy is configured to access the endpoint and have the configuration so the netNamedPipes can find the server. Has nothing to do with that – AAlferez Aug 16 '13 at 17:44
  • I did more testing, looks like whatever is done in the Callback is not executed, like is other object.How can I make sure the callback is done over the same object? – AAlferez Aug 16 '13 at 18:11
  • possible duplicate of [Wait on thread that creates an instance that creates a thread](http://stackoverflow.com/questions/18272987/wait-on-thread-that-creates-an-instance-that-creates-a-thread) – H H Aug 17 '13 at 11:27
  • @HenkHolterman post an answer so I can accept it, the issue was a wrong callback context, so it wasnt answering the same instance. Thank you :) – AAlferez Aug 19 '13 at 13:42
  • You can post an answer yourself, you have more details. Anything that might help a future googler who lands here. – H H Aug 19 '13 at 13:44

3 Answers3

2

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 :)

AAlferez
  • 1,480
  • 1
  • 22
  • 48
0

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.

alex
  • 12,464
  • 3
  • 46
  • 67
  • This background thread rules other thread with an eventhandler. And the other thread is not dead for sure.100% sure – AAlferez Aug 16 '13 at 16:20
0

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();
    }
}
Mohammad Almasi
  • 400
  • 6
  • 19