我正在创建多个线程,并且一次只执行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);
});
答案 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