MaxDegreeOfParallelism不限制并行任务的数量

时间:2019-05-22 23:08:01

标签: c#

我正在创建多个线程,并且一次只执行N个。但是我有一个问题,当执行代码时,它会立即启动所有线程。

for (int i = 0; i < Global.MyList.Count - 1; i++)
{
    Thread thread = new Thread(() =>
    {
        Debug.WriteLine("Start signal from thread", Thread.CurrentThread.Name);
        var account = Global.MyList[i];
        Thread.Sleep(5000);
        Debug.WriteLine("End signal from thread", Thread.CurrentThread.Name);
    });
    thread.Name = i.ToString();
    threads.Add(thread);
}

var option = new ParallelOptions()
{
    MaxDegreeOfParallelism = Convert.ToInt32(numThreads.Value)
};

var locker = new Object();
Parallel.ForEach(threads, option, t =>
{
    if (t.IsAlive == false)
    {
        t.Start();
    }
    var count = Convert.ToInt32(t.Name);
    Interlocked.Increment(ref count);
    lock (locker)
    {
        Debug.WriteLine("Number of active threads:" + count);
        Thread.Sleep(10);
    }
    Interlocked.Decrement(ref count);
});

2 个答案:

答案 0 :(得分:2)

您的代码实际上一次是启动个线程Action<int> action = i => { Console.WriteLine($"Starting action {i}"); Thread.Sleep(5000); Console.WriteLine($"Ending action {i}"); }; var option = new ParallelOptions() { MaxDegreeOfParallelism = 2 }; Parallel.For(0, 10, option, action); ,但是启动线程非常快,它们都将同时执行。 >

如果您的目标是仅同时执行 个线程,则需要重新设计方法。

您在创建专用线程和使用TPL时会感到奇怪。对于这种解决方案,我建议只使用TPL。

考虑以下简单得多的代码:

numThreads.Value

答案 1 :(得分:0)

在我看来,您的代码正在按预期工作。

您的ParamStr(0)中的lambda不包含实际上等待Parallel.ForEach线程结束的任何代码。因此,它会尽职尽责地使用您提供的t启动每个线程,但由于它不等待线程完成,因此看起来就像是一次启动所有线程。

这是MaxDegreeOfParallelism的工作方式的真实示例。

MaxDegreeOfParallelism

那给了我

Starting action 0
Starting action 5
Ending action 0
Starting action 1
Ending action 5
Starting action 6
Ending action 1
Starting action 2
Ending action 6
Starting action 7
Ending action 2
Starting action 3
Ending action 7
Starting action 8
Ending action 3
Starting action 4
Ending action 8
Starting action 9
Ending action 4
Ending action 9