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 :)
ManualResetEvent not working; Thread
-
24-06-2022 - |
Pergunta
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?
Solução
Outras dicas
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();
}
}