我在表单上有一个 PictureBox 控件,它应该每 100 毫秒绘制一次。
后台线程在循环中执行一些计算,并在每次迭代后触发一个事件。
编辑 (作为对评论的回复):
World world = new World();
void CreateBackgroundThread() {
Thread backgroundThread = new Thread(world.BackgroundWorkerFunction);
backgroundThread.Start();
}
public class World {
void BackgroundWorkerFunction() {
IPiece piece = PieceFactory.Create();
for (int i = 0; i < stepsCount; i++) {
piece.Calculate();
if (OnPieceStep != null) {
OnPieceStep(piece);
}
}
}
}
在主窗体内,有一个处理程序,由以下方式设置:
world.OnPieceStep += DrawScreen;
和 Invoke 包装器(因为要绘制的控件是在 UI 线程中创建的)。
void DrawScreen(IPiece piece) {
this.Invoke(new PieceStep(_drawScreen), piece);
}
void _drawScreen(IPiece piece) {
drawer.Draw(world.Board, piece);
}
现在,我希望for 循环在每次迭代后暂停 100 毫秒,所以我添加了 Thread.Sleep(100); 在触发事件之前:
for (int i = 0; i < stepsCount; i++) {
IPiece piece = Calculate();
if (OnPieceStep != null) {
Thread.Sleep(100);
OnPieceStep(piece);
}
}
但是,这不会每 100 毫秒刷新一次图片框,而是仅绘制循环的最后一次迭代,并且仅在循环完成后绘制。
Thread.Sleep 不应该暂停调用它的线程,而不是 UI 线程吗? 更新:我刚刚尝试在后台线程计算时单击应用程序。程序阻塞(“无响应”),因此 Thread.Sleep 显然是在 UI 线程上调用的。这是预期的行为还是我的线程有问题?