运行同步方法异步

Joh*_*els 0 c# asynchronous async-await

我有一个方法迭代一个对象列表,并为列表中的每个项从外部api中提取数据.

有时这可能非常慢(自然),我想将我的所有项目添加到Taks列表,而不是能够同时运行多个线程.这可能没有重写它是异步的吗?今天我正在使用WebClient并同步获取所有内容.

我一开始尝试过类似的东西:

public Main() 
{
    List<Task<Model>> taskList = new List<Task<Model>>();
    foreach (var aThing in myThings)
    {
        taskList.Add(GetStuffAsync(aThing));
    }

    List<Model> list = Task.WhenAll(taskList.ToArray()).Result.ToList();
}

public async Task<Model> GetStuffAsync(object aThing)
{
    // Stuff that is all synchronous
    // ...
    return anObject;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

您可以只GetStuff使用普通的同步方法Task.Run创建新任务(通常在多个线程上运行),而不是在此处使用异步,这样您的提取就会并行发生.您还可以考虑使用Parallel.ForEach等,这与您当前的Main代码有效相似.

你的异步方法目前不会做你想要的,因为异步方法至少同步到第一个await表达式...在你的情况下你没有任何await表达式,所以到时候GetStuffAsync返回,它已经完成所有实际工作 - 你没有并行性.

当然,另一种方法是使用当前的代码,但实际上确实是GetStuffAsync异步的.

同样值得注意的是,.NET中的HTTP堆栈具有每主机连接池限制 - 因此,如果您从同一主机获取多个URL,您可能也希望增加这些URL,或者您不会得到太多并行性.