调用线程无法访问此对象,因为另一个线程拥有它wpf

时间:2014-03-17 10:55:12

标签: wpf multithreading task-parallel-library

我是线程概念的新手。

我用相同的内容检查了问题,但与我当前的问题没有关系,这是

我在UI中有一个文本框绑定到MyViewModel.cs中的GridSize 当网格大小发生变化时,会有大量计算更新UI组件,导致应用程序冻结,所以我尝试使用TPL Task.Factory.StartNew()。

这给了我错误"调用线程无法访问此对象,因为另一个线程拥有"

我正在使用MEF导入ViewModel。

Xaml.cs文件

[Import]
public MyViewModel ViewModel
{
  get { return DataContext as MyViewModel; }
  set
  {
    if (DataContext is MyViewModel)
          ViewModel.OnModelUpdated -= ModelUpdatedEvent;

     DataContext = value;

     if (DataContext is MyViewModel)
     {
       ViewModel.OnModelUpdated += ModelUpdatedEvent;
     }
   }
}

private void ModelUpdatedEvent(object sender, EventArgs e)
{
   // code to update the UI.
}

MyViewModel.cs

public double GridSize
{
   get { return _settings.GridSize; }
   set
   {
       _settings.GridSize = value;

       ModelUpdatedEvent();
   }
}

public event EventHandler OnModelUpdated;

public void ModelUpdatedEvent()
{
    EventHandler eventModelUpdated = OnModelUpdated;
    if (eventModelUpdated != null)
    {
       Task.Factory.StartNew(()=> eventModelUpdated.Invoke(this, EventArgs.Empty));
    }
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:7)

WPF可视对象只能由创建它们的线程来操作。 TPL通过使用其他线程并行执行。

您可以使用Dispatcher.BeginInvoke()

将计算结果编组回正确的主题
Application.Current.Dispatcher.BeginInvoke(new Action(() => this.GridSize = calculatedGridSize));

根据你的评论。如果您的阻塞计算在视图中,那么您仍然需要将这些计算卸载到后面的代码中的另一个线程。您需要从实际触及视图项的代码中拆分实际计算。完成计算后,您需要以上述方式编组对可视项目的任何调用。