gpt4 book ai didi

C# - 异步/等待打印顺序

转载 作者:行者123 更新时间:2023-12-01 22:58:44 24 4
gpt4 key购买 nike

我试图了解 async 和 await 是如何工作的,所以我编写了这个小程序来尝试在“a”之前打印“b”,但它不起作用,我无法弄清楚..有什么帮助吗? :)

public class program
{
static async Task Main()
{
await a();
b();
}

async static Task a()
{
Console.WriteLine("Waiting for a");
for (int i = 0; i < 100000000; i++)
if (i % 1000000 == 0)
Console.Write(".");
Console.WriteLine("\na");
}

static void b()
{
Console.WriteLine("b");
}
}

最佳答案

让我们完善您的代码。首先它不起作用,因为您告诉代码 await a(),因此该行之后的任何内容都不能在它之前(或期间)运行。让我们修复它:

    static async Task Main()
{
var task = a();
b();
await task;
}

但这还不够,它仍然不起作用。它仍然在 b() 之前运行 a() 因为您的 a 方法不是异步的。实际上是同步的。仅仅因为您使用了 async/await 它不会使代码自动异步。你需要的不止于此。一种方法是添加 await Task.Yield() 这是真正的异步调用,即使它什么也不做(除了允许切换发生)。像这样:

    async static Task a()
{
Console.WriteLine("Waiting for a");
for (int i = 0; i < 100000000; i++)
if (i % 1000000 == 0)
{
Console.Write(".");
await Task.Yield();
}
Console.WriteLine("\na");
}

现在您将看到 b()a() 的中间运行。您可以试用 await Task.Yield(); 调用,并将其放在不同的位置以查看不同的结果。

这仍然是一个有点原始的例子。最好也使 b() 异步。并使用延迟。像这样:

public class program
{
static async Task Main()
{
var task1 = a();
var task2 = b();
await task1;
await task2;
}

async static Task a()
{
Console.WriteLine("Waiting for a");
for (var i = 0; i < 100; i++)
{
Console.Write(".");
await Task.Delay(20);
}
Console.WriteLine("\na");
}

static async Task b()
{
await Task.Delay(200);
Console.WriteLine("b");
}
}

请注意,我稍微修改了您的 a() 以便它更多地依赖于时间,更少地依赖于 cpu 速度。

当然你现在有一个线程安全问题,在这种情况下没关系,因为 ConsoleTask 方法是线程安全的。但通常你必须意识到,当两个或多个任务同时运行时,它们可能会在不同的线程上运行,因此你必须使代码线程安全。

关于C# - 异步/等待打印顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72431442/

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