2011-07-31 78 views
3

我做了一個'FlowDocument',一個WPF對象,來自DoWork的System.ComponentMode.BackgroundWorker,但我無法在WPF UI線程中訪問它。我想知道當我在另一個線程中訪問一個WPF對象時,我需要使用dispatcher()。 但RunWorkerCompleted()不是UI的另一個線程,所以我很困惑。 我如何訪問myFlowDocument?BackgroundWorker和WPF

回答

2

問題是因爲FlowDocument是在與UI線程不同的線程中創建的。

您將需要在主UI線程上創建流文檔。然後在您的後臺工作人員中,您將不得不使用流程文檔Dispatcher.Invoke來設置屬性並創建項目。在你的簡單例子中,使用後臺工作者並沒有真正的優勢。工人應該用來處理你長時間運行的過程。

唯一的另一種方式可能是在後臺工作者中創建文檔,將其序列化到內存流中,然後在您返回到UI線程後反序列化。

0

正如Bob Vale正確指出的那樣;從不在另一個線程上創建UI對象是一條通用的經驗法則。當您創建演示文稿對象時;你應該在UI線程上做到這一點。後臺任務應該返回簡單的數據。我會改變的DoWork的看起來像這樣:

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Action<string> action = r => 
     { 
      FlowDocument myFlowDocument = new FlowDocument(); 
      Paragraph myParagraph = new Paragraph(); 
      myParagraph.Inlines.Add(new Bold(new Run(r))); 
      myFlowDocument.Blocks.Add(myParagraph); 
      fviewer.Document = myFlowDocument; 
     }; 
     Dispatcher.Invoke(action, (string)e.Result); 
    } 

在這種情況下,什麼樣的調度員正在做的是讓你來安排:

private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     //Assume some kind of "work" is being done here. 
     e.Result = "Some bold text in the paragraph"; 
    } 

,那麼你可以將文檔內容的通過Dispatcher設置在擁有UI的線程中工作(在這種情況下是委託)。

+0

但fviewer和流程文檔是在單獨的線程上創建的,所以您不能將它們組合在一起。 –

+0

你的代碼沒有工作。它發生了同樣的例外。謝謝。 – mjk6026

+0

@Bob - 確實。很好的接收。我已經更新了我的答案。 – vcsjones

0

我做了一個 'FlowDocument的',一個WPF對象,從DoWork的System.ComponentMode.BackgroundWorker

不要那樣做。 UI對象需要從UI線程創建和更新。