Asynchronous 如何在展开时保留任务状态

Asynchronous 如何在展开时保留任务状态,asynchronous,.net-4.5,Asynchronous,.net 4.5,请遵守以下简单的.NET 4.5代码: var tcs = new TaskCompletionSource<object>("Hello"); var t1 = tcs.Task; var t2 = t1.ContinueWith((t, state) => 0, "Hello"); var t3 = t2.ContinueWith((t, state) => new Task<int>(_ => 0, state), "Hello"); var t4

请遵守以下简单的.NET 4.5代码:

var tcs = new TaskCompletionSource<object>("Hello");
var t1 = tcs.Task;
var t2 = t1.ContinueWith((t, state) => 0, "Hello");
var t3 = t2.ContinueWith((t, state) => new Task<int>(_ => 0, state), "Hello");
var t4 = t3.Unwrap();

Trace.Assert("Hello".Equals(t1.AsyncState), "t1.AsyncState is broken!");
Trace.Assert("Hello".Equals(t2.AsyncState), "t2.AsyncState is broken!");
Trace.Assert("Hello".Equals(t3.AsyncState), "t3.AsyncState is broken!");
Trace.Assert("Hello".Equals(t4.AsyncState), "t4.AsyncState is broken!");
var tcs=new TaskCompletionSource(“Hello”);
var t1=tcs.Task;
var t2=t1.继续((t,state)=>0,“你好”);
var t3=t2.ContinueWith((t,state)=>newtask(=>0,state),“Hello”);
var t4=t3.Unwrap();
Assert(“Hello.Equals(t1.AsyncState),“t1.AsyncState已断开!”);
Assert(“Hello.Equals(t2.AsyncState),“t2.AsyncState已断开!”);
Assert(“Hello.Equals(t3.AsyncState),“t3.AsyncState已断开!”);
Assert(“Hello.Equals(t4.AsyncState),“t4.AsyncState已断开!”);
最后一个断言失败,这破坏了我的代码(比这个示例稍微不那么做作)


我的问题是如何使任务状态在展开后仍然有效?有没有一种方法可以使用状态保留手动展开?

现在,我看不到任何其他选项,除了避免使用默认的
unwrap()
方法。相反,我发现以下解决方法是足够的:

var t4 = t3.ContinueWith((t, _) => t.Result.Result, t3.AsyncState);
我将把它打包为自己的扩展方法,类似于
FixedUnwrap()

公共静态任务FixedUnwrap(此任务)
{
返回task.ContinueWith((t,)=>t.Result.Result,task.AsyncState);
}
重要更新

提议的实施是错误的!嵌套任务完成后,展开的任务必须继续,而给定版本在包装任务完成后继续。这是非常错误的

请在下面找到正确的一个(两个版本):

公共静态任务展开(此任务)
{
返回task.Unwrap().ContinueWith((t,))=>
{
if(t.Exception!=null)
{
抛出t异常;
}
},task.AsyncState);
}
公共静态任务展开(此任务)
{
返回task.Unwrap().ContinueWith((t,)=>t.Result,task.AsyncState);
}

我不认为您的自定义展开具有相同的错误传播语义。除此之外,这似乎是一个很好的解决方案。我很乐意改进它。有什么建议吗?
public static Task<TResult> FixedUnwrap<TResult>(this Task<Task<TResult>> task)
{
  return task.ContinueWith((t, _) => t.Result.Result, task.AsyncState);
}
    public static Task TaskUnwrap(this Task<Task> task)
    {
        return task.Unwrap().ContinueWith((t, _) =>
        {
            if (t.Exception != null)
            {
                throw t.Exception;
            }
        }, task.AsyncState);
    }

    public static Task<TResult> TaskUnwrap<TResult>(this Task<Task<TResult>> task)
    {
        return task.Unwrap().ContinueWith((t, _) => t.Result, task.AsyncState);
    }