首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >WPF DependencyObject调用线程异常

WPF DependencyObject调用线程异常
EN

Stack Overflow用户
提问于 2014-11-24 00:33:44
回答 3查看 1K关注 0票数 2

我有以下代码,它创建一个临时文件夹,并使用FileSystemWatcher轮询添加到Location属性文件夹中的文件,并将它们添加到列表中:Scratchdisk.cs on Pastebin。其思想是创建一个Scratchdisk对象,并让FFmpeg将视频帧提取到其中,在FFmpeg创建这些文件时,FileSystemWatcher将构建这些文件的列表,并将该列表显示为我的UI绑定到的DependencyObject。

我像这样绑定到Scratchdisk对象:

代码语言:javascript
复制
<ItemsControl ItemsSource="{Binding Source=ThumbnailScratchdisk, Path=FileList}">
...
</ItemsControl>

但是,在实际创建对象时,我得到了以下异常:

代码语言:javascript
复制
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll

Additional information: The calling thread cannot access this object because a different thread owns it.

在第28行get { return (List<string>)GetValue(FileListProperty); }

我想我需要一个Dispatcher.Invoke,但是我不知道在哪里,我不知道在哪里创建了第二个线程。我假设这与FileSystemWatcher写入文件列表有关。

有什么帮助吗?

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2016-07-21 02:12:14

我访问它的方式是这样的。它获取UI线程的调度程序

代码语言:javascript
复制
System.Windows.Application.Current.Dispatcher.Invoke(
  (Action)(() => 
  {
      //Access the UI from here 
  }));

在我所拥有的内容和您在注释中列出的内容之间,需要注意的主要一点是,无论您是在幕后代码、视图模型、服务类中,还是在任何地方,我的代码都可以正常工作。并不是所有的项目都有Dispatcher,所以this.Dispatcher并不总是有效的。

票数 1
EN

Stack Overflow用户

发布于 2015-06-17 02:36:12

您可以将调用包装在从Dispatcher调用的Action()中,如下所示:

代码语言:javascript
复制
this.Dispatcher.BeginInvoke(new Action(() =>
{
    // your code accessing UI elements here
}));
票数 -1
EN

Stack Overflow用户

发布于 2018-09-11 03:16:33

尽管这是一个相当老的帖子,但我想给那些遇到和我一样的事情的人一个提示。这是一个故意冗长的描述,这样搜索引擎就可以为下一个遇到这种晦涩行为的人找到它。

在获得描述为here的SetValue/GetValue编译错误之后,我需要从DependencyObject派生我的VM。

我想继续从我们的ViewModelBase派生我的VM,它派生自我们的AbstractNotifyPropertyChanged类(当然,不能从C#中的两个完整类派生)。作为超级聪明的人,我想我应该将DependencyObject派生添加到我的AbstractNotifyPropertyChanged类中。我看不到任何理由为什么这个小小的改变会有任何有害的影响。几个星期以来,应用程序一直运行得很好。

然而,总是有一个很大的毛发“然而”。在测试过程中,我发现当选择一个项目时,我的一个组合框使整个应用程序崩溃。这是由于未处理的InvalidOperationException造成的。“调用线程无法访问此对象,因为另一个线程拥有它。”这个组合框唯一的不同之处在于它对某些值使用了DependencyProperty。

四天令人沮丧的调试无果而终,因为我的代码都没有发出调用。这一切都来自WPF,当调用堆栈到达GetValue中的VerifyAccess时,它就爆炸了。显然,当它被框架调用时,试图调用Invoke来跨线程是不会发生的?您将把Invoke调用放在哪里?

因为正常的调试失败了,所以我不得不通过艰难的方式来解决它。我回顾了我的签入步骤,以找到代码最后一次工作的时间。我已经有了这样的想法,它以某种方式与combobox的DependencyProperty相关,所以看到代码的变化,我的怀疑指向了DependencyObject派生。

在对代码派生进行了一些欺骗之后(通过ViewModelBase)从我的所有ViewModels链中删除了DependencyObject,并将派生只放在我需要它的确切位置,问题就解决了。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27091348

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档