2013-08-03 30 views
2

我有獲取使用Tweetsharp庫特定Twitter帳戶的鳴叫代碼,創建一個自定義UserControl和後推文文字到UserControl的實例,然後將其添加到StackPanelC#/ WPF - 我不能從一個BackgroundWorker更新UI

但是,我必須得到很多推文,看起來應用程序會凍結,同時將用戶控件添加到StackPanel。我嘗試使用BackgroundWorker,但直到現在我還沒有幸運。

我的代碼:

private readonly BackgroundWorker worker = new BackgroundWorker(); 

// This (UserControl) is used in the MainWindow.xaml 
private void UserControl_Loaded_1(object sender, RoutedEventArgs e) 
{ 
    worker.DoWork += worker_DoWork; 
    worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
    worker.RunWorkerAsync(); 
} 

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    int usrID; 

    var service = new TwitterService(ConsumerKey, ConsumerSecret); 
    service.AuthenticateWith(AccessToken, AccessTokenSecret); 
    ListTweetsOnUserTimelineOptions options = new ListTweetsOnUserTimelineOptions(); 
    options.UserId = usrID; 
    options.IncludeRts = true; 
    options.Count = 10; 
    twitterStatuses = service.ListTweetsOnUserTimeline(options); 
} 

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    try 
    { 
     foreach (var item in twitterStatuses) 
     { 
      TweetViewer tweetViewer = new TweetViewer(); // A UserControl within another UserControl 
      tweetViewer.Tweet = item.Text; 
      tweetViewer.Username = "@stackoverflow"; 
      tweetViewer.RealName = "Stack Overflow" 
      tweetViewer.Avatar = ImageSourcer(item.Author.ProfileImageUrl); 
      stackPanel.Children.Add(tweetViewer); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 

} 

我想現在要做的就是要解決不能夠執行包含在代碼的問題worker_RunWorkerCompleted一個BackgroundWorker內,但每次我試圖用執行它一個BackgroundWorker失敗&給了我喜歡的錯誤:

調用線程必須爲STA,因爲許多UI組件都需要這個。

我也試過用STA System.Threading.Thread,而不是BackgroundWorker的,但沒有運氣!

我錯過了什麼?我對WPF很陌生,我可能會忽略一些重要的東西。

+0

是在主窗口類的後臺工作方法? – ali

+0

你能告訴你如何設置'BackgroundWorker'嗎?你會在哪條線上得到例外? – YK1

+0

@ali與** BackgroundWorker **相關的所有內容都位於_MainWindow_類中使用的另一個自定義用戶控件中。 –

回答

4

由於您的後臺工作人員使用新線程,並且此線程與主UI線程不同,您會得到此異常。 爲了簡化錯誤消息,說你不能從另一個線程中改變你的UI元素,它們是獨立的。

這個answer將解決您的問題。

我也發現了這個answer從@Marc Gravell

///...blah blah updating files 
string newText = "abc"; // running on worker thread 
this.Invoke((MethodInvoker)delegate { 
    someLabel.Text = newText; // runs on UI thread 
}); 
///...blah blah more updating files 
+1

根據http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx上的說明,它只是在新線程上運行的DoWork處理程序。 –

+0

@glautrou它正在工作,但它與在'worker_RunWorkerCompleted'中執行它相同,UI凍結,直到完成所有事情。 –

+0

@AlaaJoseph:如果'它正在工作' - 那麼它是如何在worker_RunWorkerCompleted中執行它?你說'worker_RunWorkerCompleted'中有例外! – YK1