2011-01-13 59 views
4

我目前正在更新的圖表是我的形式使用背景工人更新C#圖清除系列,拋出異常。使用的BackgroundWorker

基本上,我想在清理系列之後做更多的處理,這會使GUI完全放慢 - 所以在另一個線程中需要這個。

我認爲通過將它作爲參數傳遞,我應該是安全的,但顯然不是!

有趣的是,圖表在標籤頁上。如果tabpage在後臺,我可以反覆運行,但是如果我運行它,查看圖表,再次隱藏它,然後重新運行,它會拋出異常。顯然,如果圖表在前臺也會拋出。

任何人都可以建議我可以做什麼不同嗎?

謝謝!


編輯: 我知道,這可以在形式線程來完成,當我再次分配給它。但是,使用後臺工作者的整個目的是避免整個程序停止。正如我所說的,有更多的處理比這個命令更多。

我認爲將它作爲參數傳遞將允許我在該線程中無障礙地訪問它,但有沒有機會讓這個傳遞的圖表仍然以某種方式指向原始圖表?如果是這樣,這怎麼能克服?

我想盡可能地屏蔽GUI線程 - 所以在調用每個命令時看起來毫無意義。

回答

4

如果你想先清除它,那麼在你重新顯示它之前做很多異步工作,爲什麼不在調用BackgroundWorker之前調用chart.Series.Clear();?在這種情況下,它在主UI線程上被清除,然後在再次從UI線程設置圖表之前執行som異步工作。

此外,當使用BackgroundWorker時,我會使用內置的ReportProgress和WorkerCompleted事件來避免手動跨線程調用。這是首先使用BackgroundWorker來獲得「免費」這種功能的原因的一部分。因此,設置圖表應該在WorkerCompleted中完成,以簡化代碼(即使這不是這種情況下問題的根源)。

+0

的問題是,有很多更多的處理比只是做。我想要一個背景工作者的原因是保持GUI的響應。因此,如果我調用backgroundworker,只是爲了告訴它在GUI線程中執行所有操作,沒有任何優勢。我所希望的是複製圖表,讓後臺工作人員處理它,然後將其傳回,並將新圖表設置爲舊圖表。這不可能嗎? – Mark 2011-01-13 10:50:34

1

檢查bcCharter_DoWork中的Invoke是否必需,如果是,則將Clear方法調用放入委託中。

if (InvokeRequired) 
{   

    Invoke(new MethodInvoker(delegate 
    { 
     chart.Series.Clear(); 
     e.Result=chart;    
    })); 

    return; 
} 
0

您遇到的問題是,您無法訪問除創建它們之外的線程上的UI元素。但是,您可以在調用後臺工作人員之前清除圖表。

您可以使用Control.Invoke從另一個線程手動封送UI元素對正確線程的訪問權限。

1

我同意在以前的帖子中的分析:你問一個線程訪問另一個線程的資源。
就像你使用一個BackgroundWorker我建議你使用接線員:

private void bcCharter_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Chart chart = null; 

    Dispatcher.Invoke(DispatcherPriority.Normal, 
     new Action(() => 
      { 
       chart.Series.Clear(); 
      })); 
}