0

I have a method in C# that requires waiting for an event to occur. It's sending data to a client, but it has to wait for an event Action to be fired (which is fired when a response packet is received). How to I block execution of the method until the handler is called?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
rookie1024
  • 612
  • 7
  • 18

2 Answers2

2

This solution worked nicely, and removes the handler from the event once it is no longer needed.

AutoResetEvent evt = new AutoResetEvent(false);
Action handler = () => {
  //Do stuff
  evt.Set();
}

Event += handler;
evt.WaitOne();
Event -= handler;

However, there is one major caveat (with a fairly easy workaround): The calling thread will block indefinitely until the event is called. This means that if the event is never called, your program will hang. The fix for this is to simply change evt.WaitOne(); to evt.WaitOne(SOME_TIMEOUT);

rookie1024
  • 612
  • 7
  • 18
1

An alternative would be to use a TaskCompletionSource See https://social.msdn.microsoft.com/Forums/en-US/a30ff364-3435-4026-9f12-9bd9776c9a01/signalling-await?forum=async

It then becomes:

TaskCompletionSource tsc = new TaskCompletionSource<bool>();
Action handler = () => {
  //Do stuff
  tsc.SetResult(true);
}

Event += handler;
await tsc.Task;
Event -= handler;

The referenced discussion explains why this is a more lightweight solution.

Also, it won't block the thread and allows for a timeout (in case the event is not called) and/or cancellation (in case the application is closed down) by using a CancellationTokenSource, see Timeout an async method implemented with TaskCompletionSource

Community
  • 1
  • 1
Peter Bons
  • 26,826
  • 4
  • 50
  • 74