【问题标题】:BackgroundWorker in Silverlight ViewModelSilverlight ViewModel 中的 BackgroundWorker
【发布时间】:2012-11-11 18:48:06
【问题描述】:

我在 Silverlight 视图中有一个 TabControl,我通过将其 ItemsSource 绑定到我的 ViewModel 中的 TabItems ObservableCollection 来加载选项卡。

要打开一个新标签,创建和加载它需要一点时间,我想同时运行一个 BusyIndi​​cator。

当它们在 ViewModel 中创建和加载时,如果我在调用“load”方法之前设置 IsBusy 属性,它不会显示,因为它不是异步的。

我尝试在后台工作程序中设置它,但是当我创建 TabItem 以将其添加到 TabItems 列表时它崩溃了 (UnauthorizedAccessException)。

知道吗???提前致谢。

【问题讨论】:

  • 你能发布你的 BGW 代码吗?

标签: multithreading silverlight mvvm backgroundworker


【解决方案1】:

使用任务 (AsyncCtp with Silverlight 4):

public void Load(){
    this.IsBusy = true;
    Task.Factory.StartNew(()=> DoHeavyWork())
        .ContinueWith( t => this.IsBusy = false);
}

如果您可以将新的 async/await 功能与 Async CTP 或 VS2012/Silverlight 5 一起使用,那就更好了

public async void Load(){
    try{
        this.IsBusy = true;

        await Task.Factory.StartNew(()=> DoHeavyWork());
    }
    finally
    {       
        this.IsBusy = false;
    }
}

编辑

我假设您正在后台任务中更新 ObservableCollection。这确实会给您带来问题,因为处理集合更新的处理程序不在 UI 线程中运行,因此集合更新不像绑定系统那样是线程安全的。为此,您必须将项目添加到 UI 线程中的 ObservableCollection。如果您可以一次获取所有项目,则可以这样做:

public async void Load(){
    try{
        this.IsBusy = true;

        // Returns the fetched items
        var items = await Task.Factory.StartNew(()=> DoHeavyWork());

        // This will happen in the UI thread because "await" returns the
        // control to the original SynchronizationContext
        foreach(var item in items)
            this.observableCollection.Add(item);
    }
    finally
    {       
        this.IsBusy = false;
    }
}

如果您必须批量加载,您可以使用当前的 Dispatcher 将项目添加到集合中,就像我在 this answer 中建议的那样。

【讨论】:

  • 感谢您的回答。我已经尝试了异步解决方案,但是当我创建一个新控件时我仍然得到 UnauthorizedAccessException :-(
  • 如果您从 UI 线程以外的线程更新为选项卡控件生成项目的 ObservableCollection,它确实会给您带来问题。请参阅编辑后的答案。
  • 感谢您的深入解释 :)
【解决方案2】:

当您尝试访问 UI 的元素或更改数据的集合时会发生这种情况,这些数据反过来会反映在 UI 上。这实际上是跨线程异常。当你创建一个后台工作者时,你基本上是在创建另一个线程。因此,您无法从 Background worker 访问主 UI 线程的变量。

【讨论】:

  • 现在我们知道了原因,您知道任何解决方案吗??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多