我有一个看起来像这样的方法:
while(intVariable < 4))
{
DoSomeStuff();
if (intVariable == 3)
{
FinalDecide();
}
if (rollCounter < 3)
{
Decide(args);
}
intVariable++;
}
方法Decide()运行32个线程,我想确保在循环第二次开始Decide()之前,第一次完成
在内部决策中,我有这样的东西:
for (int i = 0; i < 32; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Prepare));
t.IsBackground = true;
t.Start(i);
}
runner = new System.Threading.Thread(WaitforThreads);
runner.IsBackground = true;
runner.Start();
即使我等待这32个线程在本次Decide方法运行中完成,该代码仍会继续运行,并在第一个方法完成之前再次触发Decide方法,这会导致错误
如何确保方法Decide在第二次启动之前完成WaitforThreads()方法?
答案 0 :(得分:1)
一种实现此目的的方法是使Decide方法返回已启动线程的Thread[]
并将其保存到while循环可访问的变量中,然后在下次调用Decide之前加入所有线程:
Thread[] decideThreads = null;
while(intVariable < 4))
{
DoSomeStuff();
if (intVariable == 3)
{
FinalDecide();
}
if (rollCounter < 3)
{
if (decideThreads != null)
{
foreach (var t in decideThreads)
t.Join();
}
decideThreads = Decide(args);
}
intVariable++;
}
更好的是,您可以按照注释中的建议用Task<T>
替换线程,然后只返回Task.WhenAll
而不是Thread[]
。然后,您可以使用async
使代码更有效:
Task decideTask = null;
while(intVariable < 4))
{
DoSomeStuff();
if (intVariable == 3)
{
FinalDecide();
}
if (rollCounter < 3)
{
if (decideTask != null)
await decideTask;
decideTask = Decide(args);
}
intVariable++;
}
Decide
然后将执行以下操作:
Task[] workers = new Task[32];
for (int i = 0; i < 32; i++)
{
var localI = i; // to be captured in lambda
workers[i] = new Task(() => Prepare(localI));
}
return Task.WhenAll(workers);