C#/WPF - I can't update UI from a backgroundworker

爱⌒轻易说出口 提交于 2019-12-19 10:12:20

问题


I have a code that fetches tweets from a specific Twitter account using Tweetsharp library, creates instance of a custom UserControl and post tweet text to that UserControl then add it to a StackPanel.

However, I have to get a lot of tweets and it seems that the application would freeze while adding user controls to the StackPanel. I tried using BackgroundWorker, but I wasn't lucky until now.

My code :

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);
    }

}

What I want to do now is to solve the problem of not being able to perform the code contained in worker_RunWorkerCompleted within a BackgroundWorker but every time I try to perform it using a BackgroundWorker it fails & gives me errors like :

The calling thread must be STA, because many UI components require this.

I tried also using a STA System.Threading.Thread instead of the BackgroundWorker but without luck!

What am I missing ? I'm really new to WPF and I may be ignoring something important.


回答1:


You get this exception because your background worker uses a new thread, and this thread is different than the main UI thread. To simplify the error message says that you cannot change your UI element from another thread, they are independant.

This answer will solve your problem.

I also found this answer from @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


来源:https://stackoverflow.com/questions/18030759/c-wpf-i-cant-update-ui-from-a-backgroundworker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!