gpt4 book ai didi

c# - 为什么这个异步运行异步/线程?

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

我正在关注一篇文章,该文章展示了异步/任务如何不是线程。 https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel/

在他们的示例中,他们建立了一个异步调用,通过创建 3 个任务来显示这一点,每个任务运行一个循环,暂停数秒。我在控制台(标记为 STAThread)应用程序中重新创建了它。

但是,在我下面的代码中,我预计两个示例都需要 15 秒(每个任务 5 秒),如本文所述。但是,第二个只需要 5 秒,因此同时运行所有 3 个,导致我的第二个示例用 5 秒完成。原文章用了 5 秒,但我将其更改为延迟 1 秒,以使其更明显。

任何人都可以解释发生了什么以及为什么它看起来像线程一样运行吗?

    class AsyncTest
{
Stopwatch sw = new Stopwatch();
internal void Tests()
{
DoASynchronous1();
//update below to be DoAsync2 and repeat
}

private void DoASynchronous1()
{
sw.Restart();
var start = sw.ElapsedMilliseconds;
Console.WriteLine($"\nStarting ASync Test, interval 1000ms");
Task a=DoASync1("A",1000); //change these to 2
Task b=DoASync1("B",1000);
Task c=DoASync1("C",1000);
Task.WaitAll(a, b, c);
sw.Stop();
Console.WriteLine($"Ended Sync Test. Took {(sw.ElapsedMilliseconds - start)} mseconds");
Console.ReadKey();
}

//this runs synchronously showing async is not threaded
//this takes 15 seconds
private async Task DoASync1(string v, int delay)
{
//loop for 5 seconds
for (int i = 1; i <= 5; i++)
{
await Task.Delay(0); //or simply omit
var startTime = sw.ElapsedMilliseconds;
while (sw.ElapsedMilliseconds < startTime+(delay)) { }
Console.WriteLine($"{v}:{i}");
}
}

//this is taking 5 seconds
private async Task DoASync2(string v, int delay)
{
//loop for 5 seconds
for (int i = 1; i <= 5; i++)
{
await Task.Delay(100);
var startTime = sw.ElapsedMilliseconds;
while (sw.ElapsedMilliseconds < startTime + delay) { }
var endtime = sw.ElapsedMilliseconds;
Console.WriteLine($"{v}:{endtime}");
}
}

}
}

最佳答案

这里的关键是缺少同步上下文。链接的文章是一个 WPF 应用程序,它在其主/UI 线程上有一个同步上下文。您创建的控制台应用程序根本没有。

这样做的结果就是文章说的,例如

When you “await” an asynchronous task, the rest of your method will continue running in the same context that it started on. In WPF, that context is the UI thread.

这不适用于您的示例。 Task.Delay 之后,您的代码将在线程池线程上恢复。这允许您的所有 3 个任务并行运行。

这与文章后面使用 ConfigureAwait(false) 的情况非常相似,这会阻止在捕获的同步上下文中恢复执行。

关于c# - 为什么这个异步运行异步/线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54748649/

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