[英]Await not freeing up the calling thread in async method
我正在AsyncDemoViewModel中打印出Messages屬性字符串列表。
如果我在GetVideosSlowlyAsync()中使用Thread.Sleep(1000),則輸出為
Time spent: 4001 milliseconds
- Started on thread 18, finished on thread 18
- Started on thread 18, finished on thread 18
- Started on thread 18, finished on thread 18
- Started on thread 18, finished on thread 18
如果我在GetVideosSlowlyAsync()中使用await Task.Delay(1000),則輸出為
Time spent: 4053 milliseconds
- Started on thread 12, finished on thread 19
- Started on thread 19, finished on thread 16
- Started on thread 16, finished on thread 19
- Started on thread 19, finished on thread 9
為什么await調用不能釋放調用線程? 我期望await版本的完成時間快4倍左右。
控制器代碼:
public class AsyncDemoController : Controller
{
private DepartmentDb _db;
public AsyncDemoController(DepartmentDb db)
{
_db = db;
}
public async Task<ActionResult> Index()
{
var sw = Stopwatch.StartNew();
var v1 = await GetVideosSlowlyAsync();
var v2 = await GetVideosSlowlyAsync();
var v3 = await GetVideosSlowlyAsync();
var v4 = await GetVideosSlowlyAsync();
var vm = new AsyncDemoViewModel() {Videos = v1.Item2, Messages = new List<string>()};
sw.Stop();
vm.Messages.Add(string.Format("Time spent: {0} milliseconds", sw.ElapsedMilliseconds));
vm.Messages.Add(v1.Item1);
vm.Messages.Add(v2.Item1);
vm.Messages.Add(v3.Item1);
vm.Messages.Add(v4.Item1);
return View(vm);
}
private async Task<Tuple<string, IEnumerable<Video>>> GetVideosSlowlyAsync()
{
var t1 = Thread.CurrentThread.ManagedThreadId;
await Task.Delay(1000); // Thread.Sleep(1000);
var t2 = Thread.CurrentThread.ManagedThreadId;
return Tuple.Create(string.Format("Started on thread {0}, finished on thread {1}", t1, t2), _db.Videos.AsEnumerable());
}
}
等待方法等待GetVideosSlowlyAsync方法完成。 您需要將await移到需要操作結果的位置:
public async Task<ActionResult> Index()
{
var sw = Stopwatch.StartNew();
var v1 = GetVideosSlowlyAsync();
var v2 = GetVideosSlowlyAsync();
var v3 = GetVideosSlowlyAsync();
var v4 = GetVideosSlowlyAsync();
var vm = new AsyncDemoViewModel() {Videos = (await v1).Item2, Messages = new List<string>()};
sw.Stop();
vm.Messages.Add(string.Format("Time spent: {0} milliseconds", sw.ElapsedMilliseconds));
vm.Messages.Add((await v1).Item1);
vm.Messages.Add((await v2).Item1);
vm.Messages.Add((await v3).Item1);
vm.Messages.Add((await v4).Item1);
return View(vm);
}
您正在調用await GetVideosSlowlyAsync()
,它將返回到調用方法,直到任務完成。 如果要查看結果,則期望刪除此等待狀態。 這樣,當Task.Delay()
方法在線程池上休眠時, Task.Delay()
一個接一個地啟動所有4個GetVideosSlowlyAsync()
。
試試這個
List<Task> taskList = new List<Task>();
taskList.Add(GetVideosSlowlyAsync());
taskList.Add(GetVideosSlowlyAsync());
taskList.Add(GetVideosSlowlyAsync());
taskList.Add(GetVideosSlowlyAsync());
Task.WaitAll(taskList.ToArray())
foreach (Task task in taskList)
vm.Messages.Add(task.Result.Item1);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.