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

久未见 提交于 2019-12-24 04:09:04

问题


I have threads:

  1. UI thread with Dispatcher loop
  2. background thread that listens for messages in a queuing framework.

when a message is received, an event is fired in the background thread:

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

In UI thread I would like to await a message, something like this:

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

How to implement awaitable NextMessage method, so it does not create new thread each time?

There is SemaphoreSlim class where I can await WaitAsync, but is seems to create new thread that is blocked until SemaphoreSlim is released.

Maybe TaskCompletionSource is the way to go? Which TaskCreationOption should I use then?


回答1:


You mentioned the TaskCompletionSource and that is what I believe you need here. You'd tether it to the .Received event like so:

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

Then you could await it like this:

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


来源:https://stackoverflow.com/questions/38565478/how-to-return-awaitable-task-that-waits-for-an-event-in-dispatcher-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!