c#多个可重用的工作线程
本文关键字:工作 线程 | 更新日期: 2023-09-27 18:06:38
我试图用可重用的工作线程构建某种多线程游戏引擎。这意味着工作线程正在运行一个无限循环,并且在每次迭代之后,调用一个方法,该方法使用AutoResetEvent
挂起线程,直到下一次迭代从外部开始。效果很好。但是我想等待所有的工作线程进入等待状态。但是最后一个线程总是在第一步中被忽略。这是我的代码:
class WorkerThread
{
private readonly Game game;
private readonly Task task;
private readonly AutoResetEvent waitEvent;
private readonly AutoResetEvent finishEvent;
public string Message { get; set; }
public bool Active { get; private set; }
public WorkerThread(Game game)
{
this.game = game;
waitEvent = new AutoResetEvent(false);
finishEvent = new AutoResetEvent(false);
task = new Task(startTask);
}
public void Start()
{
task.Start();
}
public void PerformFrame()
{
finishEvent.Reset();
waitEvent.Set();
}
public void WaitForFrameToFinish()
{
finishEvent.WaitOne();
}
private void startTask()
{
WaitFrame();
run();
}
long sum;
private void run()
{
while (true)
{
sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum += i;
}
Console.WriteLine(Message);
WaitFrame();
}
}
private void WaitFrame()
{
Active = false;
finishEvent.Set();
waitEvent.WaitOne();
Active = true;
}
}
class Game
{
private readonly List<WorkerThread> workers = new List<WorkerThread>();
public Game()
{
workers.Add(new WorkerThread(this) { Message = "Worker 1" });
workers.Add(new WorkerThread(this) { Message = "Worker 2" });
workers.Add(new WorkerThread(this) { Message = "Worker 3" });
workers.Add(new WorkerThread(this) { Message = "Worker 4" });
workers.Add(new WorkerThread(this) { Message = "Worker 5" });
workers.Add(new WorkerThread(this) { Message = "Worker 6" });
}
public void Start()
{
foreach (WorkerThread worker in workers)
{
worker.Start();
}
}
public void OneFrame()
{
//start every worker
foreach (WorkerThread worker in workers)
{
worker.PerformFrame();
}
//wait for the workers to finish
foreach (WorkerThread worker in workers)
{
worker.WaitForFrameToFinish();
}
//check if there are workers still running
foreach (WorkerThread worker in workers)
{
if (worker.Active)
{
Console.WriteLine(worker.Message + " still active");
}
}
Console.WriteLine("Frame finished.'n");
}
}
有没有人知道为什么Game
不等待最后一个WorkerThread
完成它的任务?
编辑:使用ManualResetEventSlim
代替AutoResetEvent
解决了问题。但我还是不明白为什么上面的方法不管用。
我刚刚找到了解决方案。startTask
使用WaitFrame
方法来设置finishEvent
。这样WaitForFrameToFinish
就不会在第一次迭代时等待worker,因为finishEvent
已经设置好了。如果你这样做,它工作得很好:
private void startTask()
{
waitEvent.WaitOne();
waitEvent.Reset();
finishEvent.Reset();
run();
}