Mik*_*sen 11 .net asynchronous
我有两个异步方法Task<int> DoInt()和Task<string> DoString(int value).我有一个第三个异步方法,Task<string> DoBoth(int value)其目标是异步执行DoInt(),将其输出管道输出DoString(int)并产生结果DoBoth().
重要的限制是:
DoInt()或DoString(),所以我无法修改它们.DoBoth()关键是我已经有异步的方法(即返回任务),我想将数据从任务管道传输到任务,而不会阻塞,在最初的任务中返回最终结果.我可以执行以下所有操作,但不会阻塞以下代码:
代码示例:
// Two asynchronous methods from another library, i.e. can't be changed
Task<int> DoInt();
Task<string> DoString(int value);
Task<string> DoBoth()
{
return DoInt().ContinueWith<string>(intTask =>
{
// Don't want to block here on DoString().Result
return DoString(intTask.Result).Result;
});
}
Run Code Online (Sandbox Code Playgroud)
既然Task<string> DoString(int)已经是一个异步方法,我该如何干净地创建一个非阻塞的延续呢?实际上,我想从现有的Task创建一个延续,而不是从Func创建.
您可以使用TaskExtensions.Unwrap编写整个链:
Task<string> DoBoth(int value)
{
Task<Task<string>> task = DoInt(value).ContinueWith(valueTask =>
{
return DoString(valueTask.Result);
});
return task.Unwrap();
}
Run Code Online (Sandbox Code Playgroud)
请注意,这假设DoInt定义为Task<int> DoInt(int value);,与您的描述不同,但遵循您的代码示例.
如果DoInt不接受int参数(与您的声明匹配),则可能变为:
Task<string> DoBoth()
{
return DoInt().ContinueWith(t => DoString(t.Result)).Unwrap();
}
Run Code Online (Sandbox Code Playgroud)
作为额外使用的C#5和.NET 4.5(或异步目标包),您可以将其写为:
async Task<string> DoBoth(int value)
{
int first = await DoInt(value);
return await DoString(first);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
612 次 |
| 最近记录: |