4

我目前正在研究 TPL,并提出了第一个已经没有产生预期输出的测试。我的代码是错误的还是预期的结果让我感到困惑的是,我正在开始 20 次任务,除了等待什么都不做,我希望所有过程在 5 秒内完成,这需要更多时间,而且我现在有任务需要 10 秒而不是预期的 5 秒。

谢谢您的帮助。

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

namespace ConsoleApplication3Task
{
    class Program
    {
        static void Main(string[] args)
        {
            var tasks = new List<Task<string>>();
            for (var i = 0; i < 20; i++)
            {
                var task = Task.Factory.StartNew<string>((index) =>
                    {
                        var start = DateTime.UtcNow;
                        Task.Delay(TimeSpan.FromSeconds(5)).Wait();
                        var end = DateTime.UtcNow;
                        return string.Format("start={0}, duration={1} for task={2}", start.TimeOfDay, (end - start).TotalSeconds, index);
                    }, i);
                tasks.Add(task);
            }
            Task.WaitAll(tasks.ToArray());
            tasks.ForEach((t) => Console.WriteLine(t.Result));
        }
    }
}

输出是:

start=10:07:19.8499784, duration=9,4992059 for task=0
start=10:07:19.8489785, duration=9,5002058 for task=1
start=10:07:19.8499784, duration=9,4992059 for task=2
start=10:07:19.8499784, duration=9,4992059 for task=3
start=10:07:19.8499784, duration=9,4992059 for task=4
start=10:07:19.8489785, duration=9,5002058 for task=5
start=10:07:19.8489785, duration=9,5002058 for task=6
start=10:07:19.8489785, duration=9,5002058 for task=7
start=10:07:20.8481051, duration=5,0016351 for task=8
start=10:07:21.8492322, duration=5,5006984 for task=9
start=10:07:22.8483595, duration=5,5046991 for task=10
start=10:07:23.8494862, duration=5,4996981 for task=11
start=10:07:24.8486135, duration=5,0006344 for task=12
start=10:07:25.8497402, duration=5,0116365 for task=13
start=10:07:25.8507412, duration=5,0106355 for task=14
start=10:07:26.8488675, duration=5,0096356 for task=15
start=10:07:27.3499306, duration=5,0076366 for task=16
start=10:07:27.3499306, duration=5,0076366 for task=17
start=10:07:28.3530586, duration=5,0126368 for task=18
start=10:07:28.3530586, duration=5,0126368 for task=19
Press any key to continue . . .
4

1 回答 1

3

发生这种情况的原因是 TPL(实际上是线程池)限制了您一次可以创建的线程数。您不应该更改此行为,因为它会阻止同时启动的所有线程负载,这可能会导致问题。

但是,可以使用如下方式增加线程池中即时可用的线程数ThreadPool.SetMinThreads()

ThreadPool.SetMinThreads(20, 20);

不过,您几乎应该始终只出于测试目的这样做。

如果您尝试将该行添加到程序的开头,它将使其按预期运行。

另请注意,实际延迟来自此行:

Task.Delay(TimeSpan.FromSeconds(5)).Wait();

.Wait()导致线程池线程运行,并且它被限制,因此它不会立即启动。

您可以通过将该行更改为:

Thread.Sleep(TimeSpan.FromSeconds(5));

然后你会看到即使不使用线程也需要 5 秒ThreadPool.SetMinThreads(20, 20);

于 2013-06-07T10:21:42.650 回答