我有线程:
收到消息时,会在后台线程中触发事件:
messageReceiver.Received += (sender, args) => ...
在UI线程中,我想等待一条消息,如下所示:
void ButtonClicked(object sender, RoutedEventArgs e) {
await NextMessage(); //should return when messageReceiver.Received is fired
}
如何实现等待的NextMessage方法,所以每次都不创建新的线程?
有SemaphoreSlim
类,我可以等待WaitAsync,但似乎创建了新的线程,在SemaphoreSlim发布之前被阻塞。
也许TaskCompletionSource
是要走的路?那我应该使用哪个TaskCreationOption?
答案 0 :(得分:1)
你提到了TaskCompletionSource
,这就是我认为你需要的东西。你可以将它绑定到.Received
事件,如下所示:
static Task<IEnumerable<Message>> FromEvent(Receiver messageReceiver)
{
var tcs = new TaskCompletionSource<IEnumerable<Message>>();
EventHandler<IEnumerable<Message>> handler = null;
handler = (o, e) =>
{
messageReceiver.Received -= handler;
tcs.SetResult(e.Messages);
};
messageReceiver.Received += handler;
return tcs.Task;
}
然后你可以这样等待它:
// Having the async keyword is fine here since this is an event handler
async void ButtonClicked(object sender, RoutedEventArgs e)
{
var messages = await FromEvent(messageReceiver);
}