C# 异步任务未在后台运行?

C# 异步任务未在后台运行?,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,我正在使用Async,并在下面制作了一个示例程序。示例程序比较同步和异步操作所花费的时间 考虑到任务在后台线程上并行运行,我原以为异步操作将花费更少的时间。但是下面的程序同步和异步操作所用的时间相同。我想我遗漏了一些东西,但无论在哪里,我都会得到下面的示例来创建异步任务并运行它们 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading;

我正在使用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);
            }
        });
    }
}

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
命名空间异步测试{
班级计划{
专用静态长最大值=100;
静态void Main(字符串[]参数){
var startTime=DateTime.Now;
Console.WriteLine(“启动进程在”);
//Normal();//大约需要20秒
MainAsync().Wait();//大约需要20秒
WriteLine($“所用的总时间{DateTime.Now.Subtract(startTime.totalmillizes}ms”);
Console.ReadKey();
}
静态无效法线(){

对于(长i=0;i而言,只有满足以下条件,才能加快速度:

1) 拥有多个处理器

2) 并且可以分割任务,使其在处理器上平行排列


但在你的例子中,你只是在等待,没有什么东西需要平行排列。因此没有加速。

只有当你:

1) 拥有多个处理器

2) 并且可以分割任务,使其在处理器上平行排列


但在你的例子中,你只是在等待,没有任何东西在平行排列。因此没有加速。

在我看来,你犯了一个错误,用
.Wait()
启动
MainAsync
,这将阻止任务完成。在
MainAsync
中,你可能会假设启动
runner
一百次,但实际上你是在等待(使用
wait
)在
for
-循环的每次迭代中完成
runner.Run()
。 在
Runner
类的
Run
方法中,您在等待的地方启动
任务
(使用
wait
),直到任务也完成。 您还可以使用同步
线程.Sleep
调用,该调用应替换为
等待任务.Delay()

总之,您在任何地方都使用了
wait
,这会导致等待任务完成执行

例如,您可以创建这些
Task
实例,启动它们,然后使用
wait
等待它们

例如,一种“做一些繁重工作”的方法:

静态异步任务DoHeavyWork(intidx,intmax)
{

(长i=1;i在我看来,你犯了一个错误,用
启动
MainAsync
,等待()
,这将阻止任务完成。在
MainAsync
中,你可能会假设启动
runner
一百次,但实际上你会等待(通过使用
Wait
)在
for
-循环的每次迭代中,完成
runner.Run()
。 在
Runner
类的
Run
方法中,您在等待的地方启动
任务
(使用
wait
),直到任务也完成。 您还可以使用同步
线程.Sleep
调用,该调用应替换为
等待任务.Delay()

总之,您在任何地方都使用了
wait
,这会导致等待任务完成执行

例如,您可以创建这些
Task
实例,启动它们,然后使用
wait
等待它们

例如,一种“做一些繁重工作”的方法:

静态异步任务DoHeavyWork(intidx,intmax)
{

对于(长i=1;i而言,第一个问题是您仍然按顺序运行任务:

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

第二个问题是使用synchronous
Thread.Sleep
调用。将
Thread.Sleep(200)
替换为
wait Task.Delay(200)
。可以使用
Thread.Sleep
模拟某些工作,但决不将其用于TPL(异步等待)当您只想等待时。

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

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

第二个问题是使用synchronous
Thread.Sleep
调用。将
Thread.Sleep(200)
替换为
wait Task.Delay(200)
。可以使用
Thread.Sleep
模拟某些工作,但决不将其用于TPL(异步等待)当您只想等待时。

为什么您会认为在后台线程上运行的某个任务比在主线程上运行的要少花费一些时间?在这两种情况下,您都在等待它完成。无论是在主线程上运行20秒的任务还是在其他线程上运行20秒的任务,都应该无关紧要—它仍然需要20秒的时间……您在寻找吗
并行。对于
?您仍然将一个任务作为一个任务运行。无论您在哪个线程上运行它。如果您将它拆分为多个较小的任务并一起运行,那么它可以加快运行速度。如果您想在其他线程中运行此方法,则不应使用Wait方法。在该方法中,您可以使用async void或TPL。@AlexeiLevenkov我认为该运行方法将是异步的,这意味着只要我等待它,它就会与其他类似调用的任务并行运行应该创建多个线程,这显然不会发生,因为任务是按顺序运行的。为什么您会认为在后台线程上运行的某个线程比在主线程上运行的线程花费的时间要少?在这两种情况下,您都在等待它完成。20秒的任务是在主线程上运行还是在主线程上运行并不重要另一个线程-它仍然需要20秒…您是否在寻找并行的
。对于
?您仍然将一个任务作为一个任务运行。无论您在哪个线程上运行它。如果您将它拆分为多个较小的任务并一起运行,那么它可以加快速度。如果您希望运行,则不应使用等待方法
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)));