如何从第一个任务获取结果,然后在循环中使用ContinueWith将其传递给第二个任务?

问题描述 投票:0回答:2

所以这就是我正在做的:

var resultObj = GetFirstResultAsync()
     .ContinueWith(t => GetSecondResultAsync(resultObj))
     .Wait();

本质上告诉我,在声明变量之前我不能使用该变量,因此我得到了我发布的问题。我该怎么做?

这是我的目标,我有一个列表

resultObj
然后在该列表上我将循环遍历ID以获取我想要的另一个列表的数组
GetSecondResultAsync
有点深入列表,我想使用异步,因为它将使用
HttpClient
来获取数据。

c# asynchronous task
2个回答
1
投票

使用

Task
 创建一个具有与第一个任务不同类型结果的延续 
ContinueWith
并非易事。您必须使用
Unwrap
方法来展平结果
Task<Task<MySecondResult>>
,仔细处理失败和取消情况,并明确指定 将执行延续的
TaskScheduler

Task<MySecondResult> task = GetFirstResultAsync().ContinueWith(t =>
{
    if (t.IsFaulted)
    {
        TaskCompletionSource<MySecondResult> tcs = new();
        tcs.SetException(t.Exception.InnerExceptions);
        return tcs.Task;
    }
    if (t.IsCanceled)
    {
        TaskCompletionSource<MySecondResult> tcs = new();
        tcs.SetCanceled(new TaskCanceledException(t).CancellationToken);
        return tcs.Task;
    }
    return GetSecondResultAsync(t.Result);
}, TaskScheduler.Default).Unwrap();

这相当麻烦。您不希望这样的代码频繁出现在您的应用程序代码中。您可以将此功能封装在扩展方法中,例如

this
GitHub 提案中请求的
Then
/ContinueWithResult 扩展方法,或者使用 async/await 代替
ContinueWith
。 Async/await 是可组合的,因此您可以编写第三种
async
方法,将
GetFirstResultAsync
GetSecondResultAsync
组合为一个:

async Task<MySecondResult> GetSecondAfterFirstAsync()
{
    MyFirstResult result = await GetFirstResultAsync();
    return await GetSecondResultAsync(result);
}

0
投票

您应该能够通过将ContinueWith语句更改为t.Result来传递结果。比如:

var resultObj = GetFirstResultAsync()
 .ContinueWith(t => GetSecondResultAsync(t.Result));

我还没有测试过代码。

第一个运行的线程将返回一个“Task”。您必须通过 Task.Result 访问它。这是你必须使用的。

编辑:正如@fahadash所述,不应使用“wait()”。请改用“等待”。

© www.soinside.com 2019 - 2024. All rights reserved.