C#任务不像我期望的那样行事

时间:2016-02-14 11:58:28

标签: c# multithreading task difference

首先,我用Thread实现了测试逻辑:

    public void ThreadProc()
    {
        Console.Write("s");
        Thread.Sleep(1000);
        Console.Write("e");
    }

    public void TestByThread()
    {
        for (var i = 0; i < 10; i++)
        {
            Thread t = new Thread(new ThreadStart(ThreadProc));
            t.Start();
        }
    }

运行TestByThread()时,结果如下:

sssssssssseeeeeeeeee

但是当涉及到任务......

    public void TestByTask()
    {

        for (var i = 0; i < 10; i++)
        {
            Task.Run(() =>
            {
                Console.Write("s");
                Thread.Sleep(1000);
                Console.Write("e");
            });
        }
    }

执行TestByTask()时,结果很奇怪:

ssssssseesesseeeeeee

不仅char命令,而且输出速度也不同。

任务和线程之间有什么区别?

3 个答案:

答案 0 :(得分:4)

当您致电Thread.Start时,会创建一个新线程,并且所有线程都会打印s,然后等待所有线程打印e

如果是Task.Run,则任务在线程池中只有很少的线程。看起来有点奇怪,因为池中只有7个线程可用,可能是某些线程忙着做某事。因此7次任务打印s,并且所有任务都进入休眠状态,但是,队列中还有更多任务根本没有启动。

当池中的某些任务完成(打印e)时,这些任务可用于运行新任务,因此它会在待处理中启动其余任务。

答案 1 :(得分:3)

Thread.Start()启动一个新线程,其中Task.Run()计划任务。然后,该任务由下一个可用的工作线程执行。可能会发生新线程的创建,但不要依赖它。

答案 2 :(得分:3)

在第一个示例中,您手动创建10个线程并并行运行它们。并且由于每个线程在写"e"之前等待1秒,因为并行性,所有10 "s"都已写入。

使用Task.Run时,只要池中有一个可用的工作人员,就会指示CLR启动新任务。通常,您将在池中拥有与CPU核心一样多的工作者(但这不是保证),所以基本上即使您调用Task.Run 10次,这也不意味着10个线程将立即开始工作。恰恰相反,它只会启动池中当前可用的任务,然后其他任务将等待第一个任务完成,然后重新开始。