如何在Dispatcher Thread中返回等待事件的等待(任务?)

时间:2016-07-25 10:35:32

标签: wpf concurrency async-await task-parallel-library dispatcher

我有线程:

  1. 带有Dispatcher循环的UI线程
  2. 后台线程,用于侦听排队框架中的消息。
  3. 收到消息时,会在后台线程中触发事件:

    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?

1 个答案:

答案 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);
}