问题描述
我了解如何在库代码上await
等待网络请求或其他长时间运行的操作完成,但我如何才能await
在我自己的长时间运行的操作上不用忙着等待?
这是忙等待解决方案。我怎样才能让它成为事件驱动的?
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;
(这个问题与 How do I await events in C#? 完全不同,后者询问如何等待事件处理程序,但与 Promise equivalent in C# 非常相似。)
解决方法
Generally in concurrency 一个“未来”是返回值的占位符,它有一个关联的“承诺”,它被履行以传递最终的返回值。
在 C# 中,它们有不同的名称:future 是 Task 和 the promise is a TaskCompletionSource。
您可以创建一个承诺,等待它,然后在您收到回调时履行它:
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);
}