简体   繁体   中英

How do I wait for an asynchronous event to be called?

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?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM