如何 return 等待调度程序线程中的事件的可等待(任务?)

How to return awaitable (Task?) that waits for an event in Dispatcher Thread

我有话题:

  1. UI 具有 Dispatcher 循环的线程
  2. 在队列框架中侦听消息的后台线程。

收到消息后,后台线程中会触发一个事件:

messageReceiver.Received += (sender, args) => ...

在 UI 线程中,我想等待一条消息,如下所示:

void ButtonClicked(object sender, RoutedEventArgs e) {
    await NextMessage(); //should return when messageReceiver.Received is fired
}

如何实现可等待的NextMessage方法,使其不会每次都创建新线程?

SemaphoreSlim class 我可以等待 WaitAsync,但似乎创建了新线程,该线程在释放 SemaphoreSlim 之前一直处于阻塞状态。

也许 TaskCompletionSource 是正确的选择?那我应该使用哪个 TaskCreationOption?

您提到了 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);
}