异步任务没有在后台运行?

时间:2015-11-28 18:59:54

标签: c# multithreading asynchronous

我正在玩Async并在下面制作了一个示例程序。示例程序比较了同步和异步操作所花费的时间

考虑到后台线程并行运行,我期待异步操作花费的时间更少。但是下面的程序对同步和异步操作都需要相同的时间。我想我错过了一些东西,但到处都是我得到以下示例来创建异步任务并运行它们

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncTest {
    class Program {

    private static long max = 100;

    static void Main(string[] args) {
        var startTime = DateTime.Now;
        Console.WriteLine("Start Process at");

        //Normal();    //takes about 20 secs
        MainAsync().Wait();     //takes about 20 secs

        Console.WriteLine($"Total Time Taken {DateTime.Now.Subtract(startTime).TotalMilliseconds} ms");
        Console.ReadKey();

    }

    static void Normal() {
        for (long i = 0; i <= max; ++i) {
            Thread.Sleep(200);
        }
    }

    static async Task MainAsync() {
        var runner = new Runner();

        for (int i = 0; i <= 100; ++i) {
            await runner.Run(i, max / 100);
        }
    }

}

public class Runner {
    public async Task Run(int idx, long max) {
        await Task.Run(() => {
            for (long i = 1; i <= max; ++i) {
                Console.WriteLine($"Task {idx} - {i}");
                Thread.Sleep(200);
            }
        });
    }
}

}

任何帮助我在这里缺少什么?

3 个答案:

答案 0 :(得分:1)

第一个问题是您仍然按顺序运行任务:

for (int i = 0; i <= 100; ++i) {
    await runner.Run(i, max / 100);
}

您启动任务,等待它完成,然后才继续迭代。只需将其更改为:

await Task.WhenAll(Enumerable.Range(0, 101).Select(i => runner.Run(i, max / 100)));

第二个问题是使用同步Thread.Sleep调用。将Thread.Sleep(200)替换为await Task.Delay(200)。可以使用Thread.Sleep来模拟某些工作,但是当你想要等待时,永远不要将它与TPL(async-await)一起使用。

答案 1 :(得分:0)

在我看来,你错误地用div开始MainAsync,这将阻止任务完成。在.Wait()内你可以假设开始MainAsync一百次,但实际上你在runner - 循环的每次迭代中等待(通过使用await)来完成{{1} }}。 在for课程的runner.Run()方法中,您开始Run等待(使用Runner),直到完成为止。 您还可以使用同步Task调用,该调用应替换为await

总而言之,您在任何地方使用Thread.Sleep会导致等待任务,直到完成执行为止。

你可以做什么,例如正在创建这些await Task.Delay()个实例,启动它们然后使用await等待它们。

作为一个方法,做了一些繁重的工作&#34;:

Task

现在让我们开始&#34;他们直到所有人都完成了:

await

如果你在static async Task DoHeavyWork(int idx, int max) { for (long i = 1; i <= max; ++i) { Console.WriteLine($"Task {idx} - {i}"); await Task.Delay(200); } } 设置断点,你会看到,你会在所有任务完成执行之前点击这个断点(这个完整场景背后的想法是什么;-))。

答案 2 :(得分:-3)

只有在以下情况下才能加快速度:

1)拥有多个处理器

2)并且可以将任务拆分为在处理器上进行并行化。

但是在你的例子中,你只是在等待,没有什么可以平行的。所以没有加速。