gpt4 book ai didi

c# - 链接两个函数 () -> Task 和 A->Task

转载 作者:可可西里 更新时间:2023-11-01 08:55:23 25 4
gpt4 key购买 nike

不知道是不是我对TPL的理解有误,但是我很难理解如何获得以下内容:

我有两个功能

Task<A> getA() { ... }
Task<B> getB(A a) { ... }

这似乎经常发生:我可以异步地得到一个 A。给定一个 A,我可以异步地得到一个 B。

我想不出在 TPL 中将这些函数链接在一起的正确方法。

这是一个尝试:

Task<B> Combined()
{
Task<A> ta = getA();
Task<Task<B>> ttb = ta.ContinueWith(a => getB(a.Result));
return ttb.ContinueWith(x => x.Result.Result);
}

ContinueWith是我感到困惑的地方。返回的类型是“双重任务”,Task<Task<B>> .这对我来说似乎是错误的。

2011-09-30 更新:

偶然发现了扩展方法TaskExtensions.UnwrapTask<Task<T>> 上运行给一个Task<T> .因此,在我们获得 C# 5.0 之前,我可以在延续本身返回任务的情况下执行 ta.ContinueWith(a=>...).UnWrap()。

最佳答案

你的getB 必须 是一个返回 Task<B> 的方法而不是 B

问题是 ContinueWith 是:

public Task<TNewResult> ContinueWith<TNewResult>(
Func<Task<TResult>, TNewResult> continuationFunction,
CancellationToken cancellationToken
)

所以在你的情况下,因为 getB返回 Task<B> ,你正在传递一个 Func<Task<A>, Task<B>> , 所以 TNewResultTask<B> .

如果你能改变getB只返回一个 B给出 A ,那行得通……或者您可以使用:

return ta.ContinueWith(a => getB(a.Result).Result);

那么 lambda 表达式的类型将为 Func<Task<A>, B>所以ContinueWith将返回 Task<B> .

编辑:在 C# 5 中,您可以轻松编写:

public async Task<B> CombinedAsync()
{
A a = await getA();
B b = await getB(a);
return b;
}

...所以这“只是”解决最终结果的问题。我怀疑是这样的,但是有错误处理:

public Task<B> CombinedAsync()
{
TaskCompletionSource<B> source = new TaskCompletionSource();
getA().ContinueWith(taskA => {
A a = taskA.Result;
Task<B> taskB = getB(a);
taskB.ContinueWith(t => source.SetResult(t.Result));
});
return source.Task;
}

这有意义吗?

关于c# - 链接两个函数 () -> Task<A> 和 A->Task<B>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7514375/

25 4 0