有没有办法使用Task <T>作为将来值T的等待句柄?

问题描述

| 我想使用Task的方法返回值在以后变得可用时返回一个值,以便调用者可以使用Wait阻塞或附加一个延续,甚至等待它。我能想到的最好的是:
 public class Future<T> {
    private ManualResetEvent mre = new ManualResetEvent();
    private T value;
    public async Task<T> GetTask() {
        mre.WaitOne();
        return value;
    }
    public void Return(T value) {
        this.value = value;
        mre.Set();
    }
}
这样做的主要问题是mre.WaitOne()正在阻塞,因此我假设每次对GetTask()的调用都会安排一个新线程进行阻塞。有没有一种方法可以以异步方式等待WaitHandle,或者已经有一个用于构建等效功能的助手? 编辑:好的,taskcompletionsource是我正在寻找的东西吗,而我只是使自己的生活艰难?     

解决方法

        好吧,我想我应该在发布之前多挖一点。
TaskCompletionSource
正是我要的东西
var tcs = new TaskCompletionSource<int>();
bool completed = false;
var tc = tcs.Task.ContinueWith(t => completed = t.IsCompleted);
tcs.SetResult(1);
tc.Wait();
Assert.IsTrue(completed);
    ,        通过调用WaitHandle.WaitOne()来阻塞线程是不好的,但这就是事件的工作方式,所选答案没有多大意义,因为它不会异步执行任何操作。 但是,.NET框架可以利用线程池中的工作线程同时等待多个事件(请参阅ThreadPool.RegisterWaitForSingleObject)-如果您需要同时等待多个WaitHandles,这将提高应用程序的整体资源利用率时间。 因此,您可以做的是注册WaitHandle以便在辅助线程上等待,然后使用所需的连续性设置回调。 使用AsyncWaitHandle扩展库(NuGet),可以在一行中完成:
var mre = new ManualResetEvent();
T myValue = ...;
Task<T> futureValueTask = mre.WaitOneAsync().ContinueWith(() => myValue);
总体而言,我的卑鄙建议是查看代码并改为执行以下操作:
async Task MyCode()
{
  var mre = new ManualResetEvent();
  StartDoingSmthAsynchronouslyThatPulsesTheEvent(mre);
  await mre;
  // finish routine here when the event fires
}
    ,        您不能只是利用5英镑来等待。您需要一个代表工作完成的真实任务,但是如果您说出类似以下内容:
private Task<T> myRealWork; 
private T value;
// ...


public async Task<T> GetTask() 
{
    value = await TaskEx.WhenAll(myRealWork); 
    return value;
}
尽管您可能也可以等待myRealWork任务。我在您的代码中看不到实际计算值的位置。这可能需要类似:
public async Task<T> GetTask() 
{
    value = await TaskEx.RunEx(() => ComputeRealValueAndReturnIt()); 
    return value;
}