I’m new to C# and threading and i have project where i have a game of Reversi(othello) which i have to make multi-threaded, after experimenting for days I’m no further forward. I have to separate the UI from the code, basically so the processes which take a while to load do not ‘freeze’ the program, allowing the user to access the buttons and user interface bits.
I’ve looked into background worker, tasks, general threads.
Here’s a couple of key sections of code, when i click the move button i want the dowork method to run, leaving the UI interactive.
private void playerMoveButton_Click(object sender, EventArgs e)
{
_bw = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_bw.DoWork += bw_DoWork;
if (_bw.IsBusy) _bw.CancelAsync();
}
public void bw_DoWork(object sender, DoWorkEventArgs e)
{
if (gameOver)
{
moveLabel.Text = "Game Over";
moveTypeLabel.Text = "";
return;
}
// Now the computer plays
moveLabel.Text = "My Move";
// Does it have any legal moves?
int numComputerMoves = theGame.CountLegalMovesMoves();
if (numComputerMoves != 0)
{
if (computerPlayStyle == PlayStyle.RANDOM)
{
moveTypeLabel.Text = "Guessing...";
moveTypeLabel.Visible = true;
this.Refresh();
// Sleep for a little to give player time to see what's
// going on
Thread.Sleep(1000);
// get a move at random
int[] movePos = theGame.FindRandomMove();
// make move
theGame.MakeMove(movePos[0], movePos[1]);
boardLayoutPanel.Refresh();
}
else
{
moveTypeLabel.Text = "Thinking...";
moveTypeLabel.Visible = true;
this.Refresh();
// Get best move
int[] movePos = theGame.FindGoodMove(minimaxDepth);
// make move
theGame.MakeMove(movePos[0], movePos[1]);
boardLayoutPanel.Refresh();
}
}
else
{
moveTypeLabel.Text = "I've no legal moves.";
moveTypeLabel.Visible = true;
this.Refresh();
// Sleep for a little to give player time to see what's
// going on
Thread.Sleep(1000);
// Change current player
theGame.SwapCurrentPlayer();
}
//Reset for the player move
moveLabel.Text = "Your Move";
int blackScore = theGame.BlackCellCount();
int whiteScore = theGame.WhiteCellCount();
string bscoreMsg = "Black: " + blackScore;
string wscoreMsg = "White: " + whiteScore;
blackScoreLabel.Text = bscoreMsg;
whiteScoreLabel.Text = wscoreMsg;
// Does player have any legal moves
int numPlayerMoves = theGame.CountLegalMovesMoves();
if (numPlayerMoves == 0)
{
moveTypeLabel.Text = "You have no legal moves.";
playerMoveOKButton.Visible = true;
// If computer player has no legal moves game over!
if (numComputerMoves == 0)
{
gameOver = true;
}
}
else
{
moveTypeLabel.Text = "Select cell or choose";
randomMoveButton.Visible = true;
playerMoving = true;
}
}
You want delegates.
Here’s a fairly simple example of how you can go about doing this with delegates:
So basically – any time you want to update the ui from within the context of the method spun out on another thread, you simply make sure to do so by invoking the delegate void/method as needed.