我正在使用完全异步的API客户端,也就是说,每个操作都返回Task
或者Task<T>
,例如:
static async Task DoSomething(int siteId, int postId, IBlogClient client)
{
await client.DeletePost(siteId, postId); // call API client
Console.WriteLine("Deleted post {0}.", siteId);
}
Run Code Online (Sandbox Code Playgroud)
使用C#5 async/await运算符,启动多个任务并等待它们全部完成的正确/最有效方法是什么:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());
Run Code Online (Sandbox Code Playgroud)
要么:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());
Run Code Online (Sandbox Code Playgroud)
由于API客户端在内部使用HttpClient,我希望这会立即发出5个HTTP请求,并在每个请求完成时写入控制台.
我对我认为纯粹是异步程序的输出感到困惑。如您所见,没有明显的反模式(希望如此)和阻止呼叫。
slowURL
限制服务器响应10秒钟。我确实通过在10秒钟的超时时间内运行对本地服务器的调用来确认,FetchSlowAsync
在控制台中运行代码时,该方法调用有效地阻塞了主线程10秒钟。
我希望TaskScheduler不会按顺序安排调用,而是总是随机确定方法的调用顺序。las,输出始终是确定性的。
FetchSlowAsync start
FetchSlowAsync got data!
FetchAsync start
FetchAsync got data!
FetchBingAsync start
FetchBingAsync got data!
All done!
Run Code Online (Sandbox Code Playgroud)
我的问题是:是什么促使FetchSlowAsync
阻塞而不是TaskScheduler执行上下文切换到另一个异步方法,并在完成后返回到它?
下一个问题是前一个问题:async Main
在异步执行模型是并发的情况下,为什么其中的所有方法都按照被调用的相同顺序执行?
FetchSlowAsync start
FetchSlowAsync got data!
FetchAsync start
FetchAsync got data!
FetchBingAsync start
FetchBingAsync got data!
All done!
Run Code Online (Sandbox Code Playgroud)