我正在做一些C#线程。启动线程并将数据传输给它们没有问题,但我在等待它们结束时遇到问题。
我的代码如下所示。我正在使用Join()
等待线程结束,但由于某种原因我的代码不起作用。
尽管在所有活动线程上调用Join()
,主线程(即for循环)仍未被阻塞。
知道我做错了吗?
List<Thread> calculationThreads = new List<Thread>();
foreach (string calculation in calculations)
{
if (calculationThreads.Count < 5)
{
Thread calculationThread = new Thread(DoCalculation);
calculationThreads.Add(calculationThread);
calculationThread.Start(threadData);
}
else
{
// Wait for the threads to complete
foreach (Thread calculationThread in calculationThreads)
{
calculationThread.Join();
}
}
}
答案 0 :(得分:2)
第一个问题是您对else
案件的处理。如果已经存在五个线程,则代码将等待线程完成,但是它尝试添加的任务从未添加。它只会抛弃这项任务并继续下一步。
第二个问题是你没有从列表中删除任何线程,所以一旦它到达五个线程,它将永远等待。如果第一个问题没有丢弃剩下的任务,那么你的程序就会锁定。
此外,在继续工作之前等待所有五个线程完成会浪费处理时间,但这是一个较小的问题。
答案 1 :(得分:0)
我会采用一些方法来计算我已经开始的线程数,并且在每个线程的末尾我减少了计数器。
然后在你的循环开始时你可以拥有
while(counter >= 5)
{
//Wait
}
答案 2 :(得分:0)
你可以有一个等待所有线程结束的while循环。
List<Thread> calculationThreads = new List<Thread>();
foreach (string calculation in calculations)
{
if (calculationThreads.Count < 5)
{
Thread calculationThread = new Thread(DoCalculation);
calculationThreads.Add(calculationThread);
calculationThread.Start(threadData);
}
else
{
// Wait for the threads to complete
while(calculationThread.Any(x => x.IsAlive)){}
// Clearing the list
calculationThread.Clear();
}
}
如果你想在for循环之后保留线程,你应该有另一个列表来存储线程。
答案 3 :(得分:0)
您为该方法提供了多少计算?
阅读代码,如果你提供4个计算,你将启动4个线程,但实际上从未进入你执行线程的代码。加入()。
将thread.join循环移到if else语句之外。
List<Thread> calculationThreads = new List<Thread>();
foreach (string calculation in calculations)
{
if (calculationThreads.Count < 5)
{
Thread calculationThread = new Thread(DoCalculation);
calculationThreads.Add(calculationThread);
calculationThread.Start(threadData);
}
}
foreach (Thread calculationThread in calculationThreads)
{
calculationThread.Join();
}