gpt4 book ai didi

c# - IO绑定(bind)异步任务不异步执行

转载 作者:行者123 更新时间:2023-11-30 15:18:34 25 4
gpt4 key购买 nike

我花了很多时间来理解异步编程原理。但有一件事还不清楚。我被这段代码弄糊涂了:

    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

据我了解,当主线程处于 sleep 状态时,应该执行方法中的 IO 绑定(bind)操作(因为 Task.Delay 模拟 IO)并按顺序中断主线程以继续执行方法代码。所以我希望看到:

Main started.
Method entered.
Thread starting sleep.
Await 1 finished.
Await 2 finished
Thread stopped sleeping
Method completed

我知道通过 Thread.Sleep 我正在停止主线程。但据我了解 Method() 不需要线程,因为它包含 IO 绑定(bind)操作。任何人都可以解释我误解的地方吗?

我使用的 AsynContext 是 ( here )。

最佳答案

默认情况下,“await”捕获当前的 synchronization context并在原始上下文中生成延续。如果上下文未定义,则在默认线程池 (TaskScheduler.Default) 中生成延续。

我不熟悉 AsyncContext,但它可能会在一些同步良好的上下文中生成 MainAsync,并且由于 Thread.Sleep 会阻塞占用该上下文的线程,因此“await”的继续将等到上下文被释放。

这不是一个奇怪的现象,你可以在没有 AsyncContext 类的情况下重现它。尝试在 Windows 窗体应用程序中运行相同的代码,您就会看到。Windows 窗体有它自己的同步上下文,可以防止不同步的控件操作。

为了克服这个问题,您可以使用 ConfigureAwait(false) 方法告诉“await”不要捕获同步上下文。

static async Task Method()
{
Console.WriteLine($"Method entered.");

await Task.Delay(1000).ConfigureAwait(false);
Console.WriteLine($"Await 1 finished.");

await Task.Delay(1000).ConfigureAwait(false);
Console.WriteLine($"Await 2 finished");
}

await 不会尝试在现有上下文中生成延续,而是会在线程池任务中生成它。

关于c# - IO绑定(bind)异步任务不异步执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43469076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com