How can I await until I receive a callback/notification without busy-waiting?

Asked By: Anonymous

I understand how I can await on library code to wait for a network request or other long-running action to complete, but how can I await on my own long-running action without busy waiting?


This is the busy-waiting solution. How can I make it event-driven?

public async Task<DataBlock> ClickSend() {
    // await until someone calls DataReceived()
    while (_Block == null) {
        await Task.Yield();
    }
    return _Block;
}

// Something external calls this function.
// Once called, ClickSend should complete with this data.
public void DataReceived(DataBlock data_block) {
    _Block = data_block;
}
DataBlock _Block = null;

(This question is completely different from How do I await events in C#? which is asking how to await on event handlers.)


Solution

Answered By: Anonymous

Generally in concurrency a "future" is placeholder for a return value and it has an associated "promise" that is fulfilled to pass the final return value.

In C#, they have different names: the future is a Task and the promise is a TaskCompletionSource.

You can create a promise, await on it, and then fulfill it when you get your callback:

TaskCompletionSource<DataBlock> _Promise = new TaskCompletionSource<DataBlock>();

public async Task<DataBlock> ClickSend() {
    DataBlock block = await _Promise.Task;
    return block;
}

public void DataReceived(DataBlock data_block) {
    _Promise.TrySetResult(data_block);
}

Here’s an executable example.

techinplanet staff

techinplanet staff


Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen windows office 365 satın al follower kaufen instagram follower kaufen porno