【发布时间】:2017-04-18 09:59:13
【问题描述】:
我花了很多时间来了解异步编程原理。但有一件事还不清楚。我被这段代码弄糊涂了:
static async Task Method()
{
Console.WriteLine($"Method entered.");
await Task.Delay(1000);
Console.WriteLine($"Await 1 finished.");
await Task.Delay(1000);
Console.WriteLine($"Await 2 finished");
}
static int Main(string[] args)
{
Console.WriteLine($"Main started.");
return AsyncContext.Run(() => MainAsync(args));
}
static async Task<int> MainAsync(string[] args)
{
var t = Method();
Console.WriteLine("Thread starting sleep.");
Thread.Sleep(10000);
Console.WriteLine("Thread stopped sleeping");
Console.WriteLine(t.IsCompleted ? "Method completed" : "Method not completed");
await t;
return 0;
}
结果:
Main started.
Method entered.
Thread starting sleep.
Thread stopped sleeping
Method not completed
Await 1 finished.
Await 2 finished
据我了解,当主线程休眠时,应该执行来自 Method 的 IO 绑定操作(导致 Task.Delay 模拟 IO)并顺序中断主线程以继续执行 Method 代码。 所以我希望看到:
Main started.
Method entered.
Thread starting sleep.
Await 1 finished.
Await 2 finished
Thread stopped sleeping
Method completed
我知道 Thread.Sleep 我正在停止主线程。但据我了解 Method() 不应该需要线程,因为它由 IO 绑定操作组成。
谁能解释我在哪里误解它?
我正在使用的 AsynContext 是 (here)。
【问题讨论】:
-
“但据我了解,Method() 不应该需要线程,因为它由 IO 绑定操作组成” - 不,它不需要。
Task.Delay()与 IOCP 无关。 stackoverflow.com/questions/32008662/… -
@MickyD 但是 Task.Delay() 正在模拟 IO 异步操作
-
我建议您再次阅读该链接。尽管
Task.Delay()模拟了异步操作,但并非所有异步操作都是“IO 绑定”的,Task.Delay()当然也不是 IO 绑定 -
每个 Async 调用都不需要 IO 绑定,这虽然是主要目的,但这里 Task.Delay 确实代表了真正的 Async 调用,它阻止了继续,而控制权交还给调用者,这会阻止它,因此继续也无法继续
标签: c# .net multithreading asynchronous async-await