2013-03-11 78 views
1

我知道有關於這個主題的幾個主題,但我認爲我是不同的。 在我的應用程序中,我打開一個表單,用戶可以輸入一些參數進行upcomming打印。這種打印應該在後臺工作人員中運行。因此,我通過事件「OnFormClosing」來觸發該後臺工作人員。Control.Invoke()stucks

在後臺工作人員我需要訪問GUI並更改/閱讀它,所以我需要一個control.Invoke()。 「有時」Invoke一直停留在invoke調用本身,並且不執行委託。我的主線程工作正常,沒有被阻止。我仍然可以與其他的東西進行交互。張貼任何代碼之前:是否有被佈置 的任何其他條件,用於執行control.Invoke()比

  • 其他主GUI線程沒有被阻塞
  • 的contorl必須存在,創建,而不是在手柄

主線程不需要是免費的,調用被稱爲正確的?它應該繼續一旦主線程空閒...

感謝所有幫助

更新:

這裏是一個問題在線程的情況: enter image description here 主線程執行此:

Application.Run(appContext); 

所以它是空閒的。 工作者線程正在等待在這一行:

fileName = (string)cbPrintFile.Invoke(new Func<String>(() => cbPrintFile.Text)); 

其中不執行像I狀態的上方。 cbPrintFile是組合框

+0

您應該使用ReportProgress事件處理程序等向UI線程報告。請參閱http://stackoverflow.com/questions/3289920/c-sharp-how-to-report-progress-from-within-a-class-to-a-backgroundworker。 – MoonKnight 2013-03-11 09:01:49

+1

你說你打開一個表單然後用'OnFormClosing'方法觸發你的後臺工作。你使用'control.Invoke()'更新哪些控件?如果您嘗試更新試圖關閉的表單,這可能是您問題的一部分... – 2013-03-11 09:27:06

+0

+1僅用於標題與'Control.Invoke()很相似'。 – 2013-03-11 11:07:30

回答

2

Invoke是「排隊並等待它被處理」。如果它變得「卡住」,那就表明你已經死鎖了,例如因爲UI線程仍然在等待worker的事件處理程序中。如果代碼正確分離,您可以將Invoke替換爲BeginInvoke,這可讓工作人員在排隊工作後繼續工作。當然,確保UI永遠不會等待工作人員也很好。如果試圖在兩個地方持有lock(在同一個對象上),這可以意外完成。您可以通過暫停應用程序只是調查,按CTRL + d彈出線程,CTRL + dÇ看到每個調用堆棧反過來。

+0

「如果代碼正確解耦,您可以用BeginInvoke替換Invoke」,請參閱解耦的方式,請清除我的疑問。 – TalentTuner 2013-03-11 09:10:05

+0

我更新了我的帖子以顯示最新情況。我同意,如果主線程忙,這會阻止它,但事實並非如此。 「BeginInvoke」不會解決這個問題嗎?因爲它只會停留在那裏,將永遠不會像現在這樣執行。另外,如果我需要從GUI讀取的值,它將不會被返回。 – derape 2013-03-11 11:52:27