链两个函数() - GT;任务< A>和A->任务< B> [英] Chaining two functions () -> Task<A> and A->Task<B>

查看:215
本文介绍了链两个函数() - GT;任务< A>和A->任务< B>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如果我在大约TPL错误的方式在想,但我很难理解如何获得以下内容:



我有两个功能

 任务< A>木屐(){...} 
任务< B> getB(A一){...}

这似乎经常发生:我可以asyncronously得到A.并给予A,我可以异步收到b。



我不能TPL正确的方法找出连锁这些功能在一起。



下面是一种尝试:

 任务< b>结合()
{
任务< A> TA =木屐();
任务<任务< B>> TTB = ta.ContinueWith(一个= GT; getB(a.Result));
返回ttb.ContinueWith(X => x.Result.Result);
}



ContinueWith 是在那里我感到困惑。返回的类型是双重任务,任务<任务< B>> 。这在某种程度上似乎只是我错了。



更新2011-09-30:



碰巧我发现扩展方法 TaskExtensions.Unwrap 上运行的任务<任务< T>> 给予任务< T>
所以,直到我们得到C#5.0中,我可以做ta.ContinueWith(A => ...)。解开()在这样的地方延续本身返回任务的情况。


< DIV CLASS =h2_lin>解决方案

请问您的 getB 有无的是它返回的方法任务< b> ,而不是 b



问题是,< A HREF =http://msdn.microsoft.com/en-us/library/dd989582.aspx> ContinueWith 是:

 公共任务< TNewResult> ContinueWith< TNewResult>(
Func键<任务< TResult>中TNewResult> continuationFunction,
的CancellationToken的CancellationToken

所以你的情况,因为 getB 收益任务< b> ,你'重新传递一个 Func键<任务< A>中任务< B>> ,所以 TNewResult 任务< b>



如果你可以改变 getB 来刚刚返回 B 给予 A ,将工作...或者你可以使用:

 返回ta.ContinueWith(A => getB(a.Result)。结果); 



然后lambda表达式将会类型, Func键<任务< A> ,B> 所以 ContinueWith 将返回任务< B>



编辑:在C#5你可以很容易地写:

 公共异步任务< b> ; CombinedAsync()
{
A A =等待木屐();
B B =等待getB(一);
回复B;
}



...所以它的公正的工作出什么目的的问题如起来。我的犯罪嫌疑人的是这样的事情,但有错误处理:

 公共任务< B> CombinedAsync()
{
TaskCompletionSource< B>来源=新TaskCompletionSource();
木屐()ContinueWith(TASKA => {
A A = taskA.Result;
任务< B> taskB = getB(A);
taskB.ContinueWith(T = GT; source.SetResult(t.Result));
});
返回source.Task;
}



这是否有道理?


I don't know if I am thinking in the wrong way about TPL, but I have difficulty understanding how to obtain the following:

I have two functions

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

This seems to occur often: I can asyncronously get an A. And given an A, I can asynchronously get a B.

I can't figure out the correct way to chain these functions together in TPL.

Here is one attempt:

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

The ContinueWith is where I get confused. The returned type is a "double-Task", Task<Task<B>>. This somehow just seems wrong to me.

UPDATE 2011-09-30:

By coincidence I found the extension method TaskExtensions.Unwrap that operates on a Task<Task<T>> to give a Task<T>. So until we get C# 5.0, I can do ta.ContinueWith(a=>...).UnWrap() in situations like this where the continuation itself returns a task.

解决方案

Does your getB have to be a method which returns Task<B> rather than B?

The problem is that ContinueWith is:

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

So in your case, because getB returns Task<B>, you're passing in a Func<Task<A>, Task<B>>, so TNewResult is Task<B>.

If you can change getB to just return a B given an A, that would work... or you could use:

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

Then the lambda expression will be of type, Func<Task<A>, B> so ContinueWith will return a Task<B>.

EDIT: In C# 5 you could easily write:

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

... so it's "just" a matter of working out what that ends up as. I suspect it's something like this, but with error handling:

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;
}

Does that make sense?

这篇关于链两个函数() - GT;任务&LT; A&GT;和A-&GT;任务&LT; B&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆