I have to wait for an event to be triggered. My initial solution was to use AutoResetEvent
and WaitOne()
, but the event was always triggered just after the waiting timeout was over. So I went back to the approach below, but I still have the same problem. 2 or 3 seconds after the timeout is over the event gets triggered no matter what the timeout was.
_wait = true;
_delayedResponse = null;
var thread = new Thread(delegate
{
while (_wait)
{
Thread.Sleep(500);
if (_delayedResponse != null)
return;
}
});
thread.Start();
var received = thread.Join(_responseTimeout);
_wait = false;
if (!received)
throw new TimeoutException(
"Timeout for waiting for response reached.");
return _delayedResponse;
Here is the event handler code:
private void OnResponseArrived(object sender, ResponseEventArgs args)
{
_delayedResponse = args.VerificationResponse;
}
The event itself is triggered from another functions that calls the function above. Basically it looks like this:
var result = DoStuff(); // Library function that is responsible for the event
if (result.Status == Status.Wait)
Wait(); // Function above
Does anyone have an idea what causes this problem and how I can solve it?
EDIT: No longer relevant. Forwarded the OnResponseArrived event, because I found no other solution in time.
Thread.Join
is a blocking call - it'll stop the thread you're calling from doing any other work. My guess is that you're waiting for the event on a background thread, but the code that will raise your event is running on the same thread as the code you posted runs in.By calling
thread.Join
you're blocking the thread that should be doing your processing. So, you wait for your timeout to expire... then whichever method your posted code is in completes... then your processing actually happens and theResponseArrived
event is raised.It would be useful if you'd post the rest of your code, but the gist of the solution will be to run the actual work (whatever code raises the
ResponseArrived
event) in a background thread - and remove the extra threading from the code you posted.EDIT in response to comment...
In order to synchronise your two pieces of code, you can use an
AutoResetEvent
. Instead of usingThread.Sleep
and your other code, try something like this:Note that you'll need to dispose of the
AutoResetEvent
when you're done with it.