【发布时间】:2016-06-09 19:20:56
【问题描述】:
我在 C# 中有一个需要等待事件发生的方法。它正在向客户端发送数据,但它必须等待event Action 被触发(在收到响应数据包时触发)。如何在调用处理程序之前阻止方法的执行?
【问题讨论】:
标签: c#
我在 C# 中有一个需要等待事件发生的方法。它正在向客户端发送数据,但它必须等待event Action 被触发(在收到响应数据包时触发)。如何在调用处理程序之前阻止方法的执行?
【问题讨论】:
标签: c#
这个解决方案效果很好,一旦不再需要处理程序,它就会从事件中删除。
AutoResetEvent evt = new AutoResetEvent(false);
Action handler = () => {
//Do stuff
evt.Set();
}
Event += handler;
evt.WaitOne();
Event -= handler;
但是,有一个主要的警告(有一个相当简单的解决方法):调用线程将无限期地阻塞,直到事件被调用。这意味着如果从不调用事件,您的程序将悬挂。解决此问题的方法是将evt.WaitOne(); 更改为evt.WaitOne(SOME_TIMEOUT);
【讨论】:
另一种方法是使用TaskCompletionSource 请参阅https://social.msdn.microsoft.com/Forums/en-US/a30ff364-3435-4026-9f12-9bd9776c9a01/signalling-await?forum=async
然后变成:
TaskCompletionSource tsc = new TaskCompletionSource<bool>();
Action handler = () => {
//Do stuff
tsc.SetResult(true);
}
Event += handler;
await tsc.Task;
Event -= handler;
引用的讨论解释了为什么这是一个更轻量级的解决方案。
此外,它不会阻塞线程并允许使用CancellationTokenSource 进行超时(以防事件未调用)和/或取消(以防应用程序关闭),请参阅Timeout an async method implemented with TaskCompletionSource
【讨论】: