循环的C#TPL - 限制线程数

时间:2017-04-19 08:56:09

标签: c# multithreading task-parallel-library

我想只使用2个线程来进行循环。我试过这段代码:

ParallelOptions po = new ParallelOptions {
    MaxDegreeOfParallelism = 2
};

Parallel.For(0, width, po, x => {
    sb.Append(Thread.CurrentThread.ManagedThreadId);
    sb.Append(Environment.NewLine);
    for (int y = 0; y < height; y++) {
        double a = (double)(x - (width / 2)) / (double)(width / 4);
        double b = (double)(y - (height / 2)) / (double)(height / 4);
    }
});

但是当我显示Thread.CurrentThread.ManagedThreadId时,它会创建超过2个ID。我也试过在循环之前添加这段代码:

ThreadPool.SetMaxThreads(2, 2);
ThreadPool.SetMinThreads(2, 2);

但它也没有改变任何东西。有人可能知道如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

MaxDegreeOfParallelism设置将用于Parallel.For()并发线程的最大数量。这并不意味着只会使用两个线程。

在执行Parallel.For()期间,可以从线程池分配不同的线程,因为线程池线程是专门设计用于重用的。

以下程序演示。如果运行它,您将看到正在使用的不同线程的总数可能超过2,但同时使用的线程总数不会超过2.

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            ParallelOptions po = new ParallelOptions
            {
                MaxDegreeOfParallelism = 2
            };

            var activeThreads = new ConcurrentDictionary<int, bool>();

            Parallel.For(0, 100, po, x =>
            {
                activeThreads[Thread.CurrentThread.ManagedThreadId] = true;
                Console.WriteLine("Active threads: " + string.Join(", ", activeThreads.Keys));
                Thread.Sleep(200);
                activeThreads.TryRemove(Thread.CurrentThread.ManagedThreadId, out bool unused);
            });

            Console.ReadLine();
        }
    }
}