2013-02-25 127 views
0

我已經制作了一個示例程序,它在後臺線程上生成每秒2000個整數,當它結束時它會觸發一個事件,它從隨機生成的數據在GUI上繪製圖形(我有在我的線程內模擬真實測量的睡眠)。從後臺訪問GUI線程

private void SetChart(System.Windows.Forms.DataVisualization.Charting.Series series) 
{ 
    if (InvokeRequired) 
    { 
    SetChartCallback d = new SetChartCallback(SetChart); 
    this.Invoke(d, new object[] { series }); 
    } 
    else 
    { 
    chart1.Series[0] = series; 
    chart1.Series[0].Name = "Generated Data"; 
    } 
} 

我在MSDN站點上找到了這種方法。它工作正常,唯一的問題是,當我關閉應用程序。有時出現錯誤消息:

無法訪問處置的對象。
對象名稱:'Form1'。

當我關閉程序時,它會處理所有的元素,我怎樣才能防止這個錯誤發生?

+3

推薦的方法是不讓表單關閉,直到完成所有後臺線程。例如禁用關閉黃油,或重寫關閉事件以通知用戶當前正在背景中發生的事情,並稍後再試。否則,如果讓表單關閉,它將在後臺處理仍然發生時消失... – 2013-02-25 23:46:09

+0

現在我正在檢查Thread.IsAlive布爾值,但是如果它返回true並且我調用thread.Join() - 程序凍結,沒有任何反應。 – patex1987 2013-02-26 00:07:25

+0

你在哪裏調用thread.join?如果你在表單關閉時調用它,它會阻塞,直到你的後臺線程完成 - 這就是Join所做的。 – 2013-02-26 00:14:18

回答

0

解決方案可能是檢查IsDisposed。事情是這樣的:

private void SetChart(System.Windows.Forms.DataVisualization.Charting.Series series) 
{ 
    if (IsDisposed) 
     return; 

    // ... 
} 
+0

對不起,但它似乎並沒有解決問題。同樣的事情發生之前像 – patex1987 2013-02-26 00:02:56

1

您已經關閉了形式,但線程仍在運行,所以當它完成它試圖調用一個方法釋放的對象上。你的表格。

您可等待線程完成。 或者你可以以某種方式發出信號,停止創建你不再需要的整數並立即退出循環。

不要被誘惑殺死它。非常不好的習慣,你不想進入那個。

+0

在Form.FormClosed事件我正在檢查Thread.IsAlive狀態。當它返回true時,我試圖Join()線程(或者是否有任何其他方式來等待線程完成其任務?),因爲調用Join方法時整個程序會凍結。 – patex1987 2013-02-26 00:10:55

+0

加入會等待,但它會凍結你的主線程。線程是否在完成時終止。如果不是這樣,直到你發出信號纔會結束。 – 2013-02-26 00:28:54

+0

如何在完成時終止線程? – patex1987 2013-02-26 00:30:09

1

正確的做法,看起來很醜陋,很可能是抓住了異常併吞下它。表單的Dispose可能不合理,直到後臺線程退出(這種情況很容易導致死鎖);框架也沒有提供任何方法,說明在控件或表單上嘗試使用這種方法,但是如果它被丟棄,則什麼都不做。因此,你最好的辦法是編寫TryInvokeTryBeginInvoke方法,通過捕獲任何異常,如果表單已被處置,將會這樣做。您可以在這種方法中使用IsDisposed檢查,但您應該認識到,由於某些Framework怪癖,有些競爭條件無法很好地解決。