2013-03-11 28 views
1

我必須加載一個窗口,並在Window_Loaded我必須加載一些變量並顯示在窗口上。後臺線程在Window_Loaded事件線程錯誤

private void Window_Loaded_1(object sender, RoutedEventArgs e) 
{   
    BackgroundWorker worker = new BackgroundWorker(); 

    worker.DoWork += (o, ea) => 
    { 
     try 
     { 
      //code to download some variables which will show on UI of Window Loading 
     } 
     catch (Exception ex) 
     { 
      //The calling thread cannot access this object because a different thread owns it. 
     } 
    }; 

    worker.RunWorkerCompleted += (o, ea) => 
    { 

    }; 

    worker.RunWorkerAsync(); 
} 

但我得到一個線程異常。有沒有辦法在BackgroundworkerDoWork的窗口上顯示變量值?

回答

4

您應該在DoWork部分檢索所需的數據,然後將其分配到ea.Result,這將使其在RunWorkerCompleted部分中可用。

RunWorkerCompleted部分,您可以再次訪問ea.Result,鑄造對象還給你DoWork指定任何類型,並根據需要對你的UI控件應用數據。

worker.DoWork += (o, ea) => 
{ 
    ea.Result = GetMyData(); 
}; 

worker.RunWorkerCompleted += (o, ea) => 
{ 
    var myData = (myDataType)ea.Result; 

    // Assign myData as needed to UI components... 
}; 
+0

我有數百個需要在UI中顯示的變量以及DoWork中正在計算的變量。但使用上面的方法我只能在UI上顯示一個變量。我對麼 ? – 2013-03-12 06:52:11

+2

@АндрейПро使GetMyData()返回一個包含所有必需變量的對象。 – Eirik 2013-03-12 08:17:14

1

您需要讓Dispatcher安排您的代碼在UI線程上執行並編組必要的參數。嘗試是這樣的:

Dispatcher.Invoke(
    new Action<string>(() => 
    { 
     // Access UI from here 
    }), 
    DispatcherPriority.Normal 
); 

雖然這個(或這樣的事情,因爲這是記事本的代碼),將解決你的問題,你應該考慮在您的實現使用MVVM模式。然後,您將能夠對ViewModel進行更改(只需更新數據),UI將相應更新。

+0

如果您只是使用Invoke,則可以擊敗使用後臺工作者的全部目的。 BGW的目的是隻要您使用適當的事件,它就會爲您處理編組。 – Servy 2013-03-11 14:05:51

+0

您還通過爲WPF使用'BackgroundWorker'來挫敗數據綁定和線程池的用途,但是我試圖快速解決特定問題,並且如果時間允許要求實現它的人提出更好的建議。 – 2013-03-11 14:09:01

+0

他選擇使用BGW,他沒有選擇使用數據綁定。關於數據綁定,完全不使用某些東西和錯誤地使用您選擇使用的東西是有區別的。關於線程池,不應該使用線程池執行單個長時間運行的操作*。線程池用於大量的短期操作,所以如果他使用線程池,它可能會誤用它。 – Servy 2013-03-11 14:21:00