I have a PictureBox control on a Form that is supposed to draw something every 100ms.
The background thread performs some calculation in a loop and after every iteration, it fires an event.
Edited (as a reply to a comment):
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);
}
}
}
}
Inside the main form, there is a handler, set by:
world.OnPieceStep += DrawScreen;
and the Invoke wrapper (since the control to be drawn to, is created in the UI thread).
void DrawScreen(IPiece piece) {
this.Invoke(new PieceStep(_drawScreen), piece);
}
void _drawScreen(IPiece piece) {
drawer.Draw(world.Board, piece);
}
Now, I'd like the for loop to pause 100ms after each iteration, so I added Thread.Sleep(100); before firing an event:
for (int i = 0; i < stepsCount; i++) {
IPiece piece = Calculate();
if (OnPieceStep != null) {
Thread.Sleep(100);
OnPieceStep(piece);
}
}
This however does not refresh the pictureBox every 100 ms, but draws only the last iteration of the loop, and only after the loop finishes.
Shouldn't Thread.Sleep pause the thread it is called on, not the UI thread? Update: I have just tried to click on the app while the background thread calculates. The program blocks ("not responding"), so the Thread.Sleep was obviously called on UI Thread. Is this expected behaviour or something is wrong with my threading?