C#并行执行线程限制

时间:2018-01-19 19:06:22

标签: c# multithreading concurrency

我正在编写一个简单的测试,它只记录并发请求开始的时间,然后休眠一秒钟。

static void TestParallelism()
{
    int expectedThreadCount = 100;
    ThreadPool.SetMaxThreads(Environment.CurrentManagedThreadId, expectedThreadCount);
    var module = new WCFCompositeModule();
    module.Initialize(new Keywords());

    var range = Enumerable.Range(0, expectedThreadCount);
    var startTimes = new ConcurrentBag<DateTime>();

    var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = expectedThreadCount };
    Parallel.ForEach(range, i =>
    {
        startTimes.Add(DateTime.Now);
        Thread.Sleep(1000);
    });

    foreach (var time in startTimes)
    {
        Console.WriteLine(string.Format("{0: HH:mm:ss.fff}", time));
    }

    Console.ReadLine();
}

当我用100个预期的线程执行此操作时,我可以看到12个不同的不同开始时间,每个都变化1秒。而不是看到它们都在同一秒开始。

样品

  

13:59:27.475   13:59:26.473   13:59:25.473   13:59:24.471   13:59:23.470   13:59:22.469

这是因为睡眠会阻塞线程吗?

1 个答案:

答案 0 :(得分:4)

您似乎期望此代码启动100个线程,但是

MaxDegreeOfParallelism = expectedThreadCount 

只设置一个最大值,而不是最小值,系统会将它发送给许多(最多MaxDegreeOfParallelism)线程。

除非你有100个核心机器,否则它不可能耗尽100个线程,所以它使用X线程然后它们都会阻塞1秒钟,然后再发送同一个X线程。这里x是100/12 = 8.333333,所以如果你看到12个不同的时间它至少开始12个不同的批次,这意味着它一次执行8到9个线程,如果你有4个核心具有超线程或8核系统的系统这可能是默认行为。