【问题标题】:C#/WPF - I can't update UI from a backgroundworkerC#/WPF - 我无法从后台工作人员更新 UI
【发布时间】:2013-08-03 08:12:46
【问题描述】:

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

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

}

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

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

我也尝试使用 STA System.Threading.Thread 代替 BackgroundWorker,但没有运气!

我错过了什么?我真的是 WPF 新手,我可能忽略了一些重要的事情。

【问题讨论】:

  • 您的后台工作方法是否在 MainWindow 类中?
  • 您能展示一下您是如何设置BackgroundWorker 的吗?你在哪一行得到异常?
  • @ali 与 BackgroundWorker 相关的所有内容都在 MainWindow 类中使用的另一个自定义用户控件中。
  • @YK1 将所有内容添加到上面的代码中。 foreach 块中的所有内容似乎都会导致异常。
  • 如果您是 WPF 新手,您可能不知道 MVVM 模式。如果你在做 WPF,你应该使用 MVVM。如果您使用的是 MVVM,您可能不会遇到此问题。

标签: c# wpf multithreading backgroundworker ui-thread


【解决方案1】:

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

这个answer 会解决你的问题。

我还从@Marc Gravell 找到了这个answer

///...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

【讨论】:

  • 根据msdn.microsoft.com/en-us/library/… 上的注释,它只是在新线程上运行的 DoWork 处理程序。
  • @glautrou 它正在工作,但它与在worker_RunWorkerCompleted 中执行它相同,UI 冻结,直到一切都完成。
  • @AlaaJoseph:如果It's working - 那么the same as performing it in the worker_RunWorkerCompleted 怎么样?你说worker_RunWorkerCompleted有例外!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 2019-08-09
相关资源
最近更新 更多