Big*_* AL 0 c# asynchronous async-await
TL; DR:
是否可以仅使用一个线程启动一系列IO绑定任务async await?
简而言之:
努力学习async await.在本视频("C#和Visual Basic的异步最佳实践")中,演讲者举例说明了async await如何启动一些IO绑定工作.他明确地说(在21分40秒)同时解释了为什么并行for循环不是最佳的,因为它们耗尽了线程的负载:
我们不需要更多线程.我们不需要两个线程......
我们真的可以在不使用多个线程的情况下异步启动多个请求吗?怎么样?不幸的是,发言人没有提供所有的代码,所以这是我的努力:
// Pretty much exactly the same as video
private async Task<List<string>> LoadHousesAsync()
{
// Running on the UI thread
Debug.Print("Thread: " + Thread.CurrentThread.ManagedThreadId);
var tasks = new List<Task<string>>();
for (int i = 0; i < 5; i++)
{
Task<string> t = LoadHouseAsync(i);
tasks.Add(t);
}
string[] loadedHouses = await Task.WhenAll(tasks);
return loadedHouses.ToList();
}
// My guess of the LoadHouseAsync method
private Task<string> LoadHouseAsync(int i)
{
// Running on the UI thread
Debug.Print("Thread: " + Thread.CurrentThread.ManagedThreadId);
return Task.Run(() => LoadHouse(i));
}
// My guess of the LoadHouse method
private string LoadHouse(int i)
{
// **** This is on a different thread :( ****
Debug.Print("Thread: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000); // simulate I/O bound work
return "House" + i;
}
Run Code Online (Sandbox Code Playgroud)
这是输出.
Thread: 10
Thread: 10
Thread: 3
Thread: 10
Thread: 10
Thread: 11
Thread: 10
Thread: 12
Thread: 10
Thread: 13
Thread: 14
Run Code Online (Sandbox Code Playgroud)
您可以使用异步I/O执行此操作.你做的是做错的一个非常好的例子(不幸的是,它也很常见).
Task.Run在线程池线程上运行一个方法,Thread.Sleep阻塞该线程.因此,您的示例模拟在多个线程上执行同步(阻塞)I/O.
要正确执行异步I/O,您需要始终使用异步方法.永远不要Task.Run用于I/O. 您可以使用Task.Delay以下方法模拟异步I/O方法:
private async Task<string> LoadHouseAsync(int i)
{
Debug.Print("Thread: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(5000); // simulate async I/O bound work
return "House" + i;
}
Run Code Online (Sandbox Code Playgroud)