我正在構建一個國際象棋遊戲,我有一個遍歷對象數組的循環,並在winforms上繪製棋子的圖像(每個圖片框代表一塊)。Winform問題上的多線程和繪圖圖像
public void PrintPieces(Pieces [,] pieces)
{
for (int i = 1; i < 9; i++)
{
for (int j = 1; j < 9; j++)
{ //pieces is an array of chess piece objects (pawn, king, bishop king etc)
if (pieces[i, j] is Object)
{
try
{
//The path of the image is obtained.
chessPics[i, j].Load(pieces[i, j].print());
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.StackTrace);
}
}
else
{ //chesspics is an array of pictureboxes
chessPics[i, j].Image = null;
}
}
}
}
上述方法的工作原理! 我有更多的遊戲代碼..但在這裏是無關緊要的,
我還添加了一個涉及背景工作的重放功能。
public void ReplayGame()
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.RunWorkerAsync();
}
該功能在每次「重放」按鈕按下時觸發。
在上面的方法中,我得到一個競爭條件和2個線程相互碰撞..(同時進入循環)。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//replay is an array of the chess moves that were made since
the start of the game.
foreach (KeyValuePair<int, int[]> item in replay)// count should be more than 2
{
if (!backgroundWorker1.CancellationPending)
{
//There is more code here that wasnt presented
//It basically executes each move from the replay
//array and return the chess pieces array (the positions
//of the current game after each move from teh replay array
//was executed)..The current game state returns in a form
//of an array and returns from the method:
PrintPieces(codeFile.PieceState());
}
else
{
break;
}
System.Threading.Thread.Sleep(1000);
}
//After the loop ends i am trying to cancel the operation of the background //worker...but that seems useless.
backgroundWorker1.CancelAsync();
}
確實發生在遊戲中這是什麼:
我按下重播按鈕once..The的所有棋被成功地重播。
當我再次按下重放按鈕(重播結束後)..異常無效操作異常發生..異常被捕獲在PrintPieces循環方法的try catch中。並且出現一個帶有此堆棧跟蹤的文本框:
at System.Drawing.Image.get_FrameDimensionsList
這個錯誤我第二次按下按鈕重放..(這表明一個運行條件/多線程進入循環)之後隨機地發生。
我閱讀更多關於異常...:
System.InvalidOperationException:對象正在使用 別處。
GDI +抱怨試圖使用 的設備上下文(DC)已被「使用」。使用winforms通常意味着遞歸Graphics.GetHdc必須與任何其他 GetHdc之前的ReleaseHdc匹配。
如果您從多個線程繪製表單,則會發生此錯誤。 交叉線程異常也可能發生。
可能的解決方案是在訪問表單(包括線程)時不使用多個線程。
InvalidOperationException用於調用 方法失敗的原因是由無效參數以外的原因引起的情況。對於 示例,InvalidOperationException拋出如下:
如果在創建枚舉數 後修改了集合的對象,則MoveNext。
我認爲doWork事件處理程序方法中的循環需要保護......我需要在另一個runAsync啓動之前終止RunAsync..and證明不成功..
的任何解決方案,將有助於
注:提供了更多的代碼比我只要你在這裏難道不添加anything..I對竊聽一整天的工作。我知道!!
我確實展示了該方法在打印方法中的外觀。看上面那個第一個方法..它打印pieces數組(一個所有棋子對象的數組..每個棋子在2維piecs數組中有一個位置..例如kingChessPiece對象是分片的[8,4 ] ..我會測試你的代碼,現在.. – Matrix001
我也認爲線程工作的速度比winform能夠更快,更慢...缺少同步 – Matrix001
哇,它不會引發異常。爲什麼它會起作用? – Matrix001