2

我有一个代码,它使用Tweetsharp库从特定 Twitter 帐户获取推文,创建自定义实例并将推UserControl文文本发布到该实例,UserControl然后将其添加到StackPanel.

但是,我必须收到很多推文,并且似乎在将用户控件添加到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);
    }

}

我现在要做的是解决无法在 a 内执行worker_RunWorkerCompleted 中包含BackgroundWorker的代码的问题,但是每次我尝试使用 a 执行它BackgroundWorker都会失败并给我如下错误:

调用线程必须是 STA,因为许多 UI 组件都需要这个。

我也尝试使用STA System.Threading.Thread而不是 BackgroundWorker 但没有运气!

我错过了什么?我对 WPF 真的很陌生,我可能忽略了一些重要的事情。

4

1 回答 1

4

您收到此异常是因为您的后台工作人员使用了一个新线程,并且该线程与主 UI 线程不同。为了简化错误消息,您不能从另一个线程更改您的 UI 元素,它们是独立的。

这个答案将解决您的问题。

我还从@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
于 2013-08-03T08:22:46.767 回答