Question

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.

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top