【问题标题】:How to have a method return a started Task without blocking?如何让方法在不阻塞的情况下返回已启动的任务?
【发布时间】:2020-02-22 01:35:10
【问题描述】:

在我的 C# 应用程序中,我已经能够启动进行 http 调用的并发任务,然后等待所有任务完成。

var responseTasks = new List<Task<HttpResponseMessage>>();

// PostChanges makes an async http call and returns the task
responseTasks.Add(myServiceClient.PostChanges(json));
responseTasks.Add(myServiceClient.PostChanges(json));
responseTasks.Add(myServiceClient.PostChanges(json));

Task.WaitAll(responseTasks.ToArray());

但是,如果对 PostChanges 的每个调用都依赖于从 http 请求中获取数据的调用呢?创建封装两个调用并返回已启动任务的方法的最简单方法是什么?该方法必须使两个请求都像这样:

public Task<HttpResponseMessage> GetDataAndPostChanges(MyInput input)
{
    var json = myServiceClient.GetData(input); // this call must complete first
    var response = myServiceClient.PostChanges(json);
    return response; // how to actually return a task immediately that does both calls?
}

然后我想对该方法进行并发调用并等待它们全部完成。

var responseTasks = new List<Task<HttpResponseMessage>>();

// PostChanges makes an async http call and returns the task
responseTasks.Add(myServiceClient.GetDataAndPostChanges(input1));
responseTasks.Add(myServiceClient.GetDataAndPostChanges(input2));
responseTasks.Add(myServiceClient.GetDataAndPostChanges(input3));

Task.WaitAll(responseTasks.ToArray());

【问题讨论】:

  • 等待函数中的PostChangesGetData 是同步还是异步?
  • 现在GetData不是异步的,只是在HttpClient上调用GetAsync,将响应内容作为对象列表返回,所以可以变成异步方法。

标签: c# asynchronous task


【解决方案1】:

使函数异步并等待必要的调用

public async Task<HttpResponseMessage> GetDataAndPostChanges(MyInput input) {
    var json = await myServiceClient.GetData(input); // this call must complete first
    var response = await myServiceClient.PostChanges(json);
    return response;
}

上面的假设是GetData是一个异步函数。

【讨论】:

  • 我假设通过这个实现,在 GetData 完成之前不会调用 PostChanges?
  • @JimSweeney 这是正确的。代码将等待 GetData 然后调用 PostChanges
猜你喜欢
  • 2019-10-23
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 2013-09-12
  • 2020-02-06
  • 2013-04-10
相关资源
最近更新 更多