我正在研究一個多線程應用程序,它需要更新Winforms控件(DataGridView)。爲了防止同一共享資源的多個訪問,我開始了下面的鎖結構:使用Control.Invoke()代替鎖定(控制)
if (DGV.Columns.Count >= DesiredColumnCount) return;
lock(DGV)
{
while (DGV.Columns.Count < DesiredColumnCount)
{
DGV.Columns.Add(newColumn);
}
}
我後來意識到,由於DGV是在UI線程上創建的,它需要.Invoke()
「d 。這將代碼更改爲:
我的問題是:這不是多餘的嗎? lock
將阻止工作線程,直到它具有對DGV
的獨佔訪問權限,並且Invoke()
將阻塞工作線程,直到UI線程可以接收調用請求並執行代碼。我不能只通過使用Invoke()
?
(這是最主要的問題。當然,如果在上面的代碼中任何其他多線程的罪過,請評論)
你對「工作者線程」有什麼用? –
你不應該阻止UI線程。這適用於鎖定以及Control.Invoke。您應該擺脫鎖定並將Invoke更改爲BeginInvoke。 –
@PeterRitchie我不記得究竟是什麼啓動了線程。它可能是'new Thread().Start()'或'System.Threading.Timer.Elapsed'。這段代碼不會阻塞UI線程,它會阻止工作者。 BeginInvoke不能盲目取代Invoke,因爲它不會阻塞調用者:我需要對調用進行排隊,以確保它們不會以錯誤的順序執行而跳過彼此。這可以通過減少阻塞工作線程所花費的時間來提高性能,但這是迄今爲止的一箇舊項目。 – Nathan