What am I missing in this simple test to see how parallel tasks could be run in C# (they're processing sequentially)?

huangapple go评论63阅读模式
英文:

What am I missing in this simple test to see how parallel tasks could be run in C# (they're processing sequentially)?

问题

以下是您提供的代码的中文翻译:

我已经阅读了关于并行任务的一堆问题和答案,并希望创建一个简单的测试,以确保我理解了它的基本工作原理。

public async Task sleeper(int s)
{
    Thread.Sleep(s);
}

public async Task t1()
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine("T1: " + i);
        await sleeper(5000);
    }
}

public async Task t2()
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine("T2: " + i);
        await sleeper(3000);
    }
}

public async Task runIt()
{
    var task1 = t1();
    var task2 = t2();
    await Task.WhenAll(task1, task2);
    Console.WriteLine("got it");
}

希望这可以帮助您理解代码的含义。

英文:

I've read through a bunch of questions and answers on running parallel tasks and wanted to make a simple test that would let me know I understood the basics of how it works.

    public async Task sleeper(int s)
    {
        Thread.Sleep(s);
    }

    public async Task t1()
    {
        for (int i=0; i&lt;10; i++)
        {
            Console.WriteLine(&quot;T1: &quot; + i);
            await sleeper(5000);
        }
    }

    public async Task t2()
    {
        for (int i=0; i&lt;10; i++)
        {
            Console.WriteLine(&quot;T2: &quot; + i);
            await sleeper(3000);
        }
    }

    public async Task runIt()
    {
        var task1 = t1();
        var task2 = t2();
        await Task.WhenAll(task1, task2);
        Console.WriteLine(&quot;got it&quot;);
    }

I expected something like:
T1: 0
T2: 0
T1: 1
T1: 2
T2: 1
etc

instead I get sequential processing of t1 and t2:
T1: 0
T1: 1
T1: 2
...
T1: 9
T2: 0
T2: 1
etc

I'm sure I'm missing something silly but maybe I'm not the only one. What's wrong here?

答案1

得分: 3

你已经接近了,而且你的想法是正确的,但你实际上没有利用 async/await,因为你在 sleeper 函数内没有使用 await 来等待任何事情。

异步代码的思想是在等待需要一段时间的操作时,线程可以去做其他事情。Thread.Sleep 用于阻塞线程指定的时间,这意味着线程被阻塞住了,不能去做其他事情。

在这种情况下,这会导致你的代码同步运行。在其他情况下,在异步调用中阻塞线程可能会导致更糟糕的问题。

为了修复你的示例,不要使用 Thread.Sleep,因为它不适用于异步操作,请使用 Task.Delay

public async Task sleeper(int s)
{
    await Task.Delay(s * 1000); // Task.Delay 的时间单位是毫秒
}
英文:

You're close, and you have the right idea, but you're not actually utilising async/await, because you're not await-ing anything inside sleeper.

The idea behind asynchronous code is for the thread to go an do something else while it waits for a thing that takes a while. Thread.Sleep is used to block a thread for the specified amount of time, which means that thread is stuck; it can't go do something else.

In this case, that causes your code to run synchronously. In other cases, blocking a thread within async calls can be much worse.

So to fix your example, instead of using Thread.Sleep, which is not intended for asynchronous use, use Task.Delay, which is.

public async Task sleeper(int s)
{
    await Task.Delay(s * 1000); // Task.Delay is in milliseconds
}

huangapple
  • 本文由 发表于 2023年5月30日 11:42:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76361488.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定