C# 是否有使用Task的方法<;T>;作为未来值T的等待句柄?

C# 是否有使用Task的方法<;T>;作为未来值T的等待句柄?,c#,task-parallel-library,async-await,async-ctp,C#,Task Parallel Library,Async Await,Async Ctp,我想使用Task return from a method在稍后可用时返回一个值,以便调用方可以使用Wait阻止或附加一个continuation,甚至可以等待它。我能想到的最好的办法是: public class Future<T> { private ManualResetEvent mre = new ManualResetEvent(); private T value; public async Task<T> GetTask() {

我想使用Task return from a method在稍后可用时返回一个值,以便调用方可以使用Wait阻止或附加一个continuation,甚至可以等待它。我能想到的最好的办法是:

 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();
    }
}
公共类未来{
private ManualResetEvent mre=新的ManualResetEvent();
私人T值;
公共异步任务GetTask(){
韦通先生();
返回值;
}
公共无效返回(T值){
这个值=值;
mre.Set();
}
}
这方面的主要问题是mre.WaitOne()正在阻塞,所以我假设对GetTask()的每次调用都会安排一个新线程来阻塞。是否有方法以异步方式等待WaitHandle,或者是否已经有帮助程序来构建等效功能


编辑:好的,TaskCompletionSource是我正在寻找的,我只是让自己的生活变得艰难吗?

你不能利用TaskEx.whalll(t1、t2、t3…来等待吗。你需要一个真正的任务来代表工作的完成,但是如果你说的是:

private Task<T> myRealWork; 
private T value;
// ...


public async Task<T> GetTask() 
{
    value = await TaskEx.WhenAll(myRealWork); 
    return value;
}
public async Task<T> GetTask() 
{
    value = await TaskEx.RunEx(() => ComputeRealValueAndReturnIt()); 
    return value;
}
私有任务myRealWork;
私人T值;
// ...
公共异步任务GetTask()
{
值=等待TaskEx.WhenAll(myRealWork);
返回值;
}
虽然你也可以等待myRealWork任务。我在你的代码中没有看到实际计算值的地方。这可能需要类似于:

private Task<T> myRealWork; 
private T value;
// ...


public async Task<T> GetTask() 
{
    value = await TaskEx.WhenAll(myRealWork); 
    return value;
}
public async Task<T> GetTask() 
{
    value = await TaskEx.RunEx(() => ComputeRealValueAndReturnIt()); 
    return value;
}
公共异步任务GetTask()
{
value=wait TaskEx.RunEx(()=>ComputeRealValueAndReturnIt());
返回值;
}

好吧,我想我应该在发帖前多挖一点
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);
var tcs=new TaskCompletionSource();
bool completed=false;
var tc=tcs.Task.ContinueWith(t=>completed=t.IsCompleted);
tcs.SetResult(1);
tc.Wait();
Assert.IsTrue(已完成);

通过调用WaitHandle.WaitOne()阻塞线程是不好的,但事件就是这样工作的,所选答案没有多大意义,因为它不会异步执行任何操作

但是,.NET framework可以利用线程池中的工作线程来同时等待多个事件(请参见t)-如果您需要同时等待多个WaitHandle,这将提高应用程序中的总体资源利用率

因此,您可以做的是注册等待工作线程的WaitHandle,并使用所需的延续设置回调。 使用AsyncWaitHandle扩展库()可以在一行中完成:

var mre = new ManualResetEvent();
T myValue = ...;
Task<T> futureValueTask = mre.WaitOneAsync().ContinueWith(() => myValue);

我想解决的问题是我没有电脑,但是其他线程独立于请求需要值的任务生成。我也使用TaskCompletionSource来解决这个问题-对我来说,它是一个更优雅的等待句柄,因为它更能表达您的原始操作。表示取消或异常对于级联到消费者非常有用。:)