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

标签 c# wpf invoke invalidoperationexception

我正在使用第三方工具,在其中我得到了一个 InvalidOperationException(实际上,最后这发生在 PresentationFramework.dll 中):

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

我尝试了使用 Invoke 的各种变体,包括 BeginInvoke,但没有任何变化。

Session session = new ThirdPartyTool.Session();
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => session.Open(view)));

使用 Google 时,我只找到建议使用 Invoke 的“解决方案”。好吧,我确实使用 Invoke。
其他问题及其在 stackoverflow 上的相应答案也无济于事。

我还能做些什么来追查真正的原因?


编辑: 我又看了看线程窗口,完整的调用堆栈在主线程中。据我所知,这表明 Invoke 是多余的。


编辑2:
调用打开时不会直接引发错误。 ThirdPartyTool 初始化一个列表框,当测量这个列表框时,在表示框架中出现错误:

enter image description here

实际异常被包装到 XamlParseException 中。完整的异常详细信息:

System.Windows.Markup.XamlParseException occurred  
HResult=-2146233087  
Message=The calling thread cannot access this object because a different thread owns it.  
Source=PresentationFramework  
LineNumber=0  
LinePosition=0  
StackTrace:  
  at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)  
InnerException: System.InvalidOperationException  
  HResult=-2146233079  
  Message=The calling thread cannot access this object because a different thread owns it.  
  Source=WindowsBase  
  StackTrace:  
    at System.Windows.Threading.Dispatcher.VerifyAccess()  
    at System.Windows.Freezable.get_IsFrozen()  
    at System.Windows.Controls.Image.UpdateBaseUri(DependencyObject d, ImageSource source)  
    at System.Windows.Controls.Image.OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
    at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)  
    at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)  
    at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)  
    at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)  
    at System.Windows.FrameworkTemplate.ReceivePropertySet(Object targetObject, XamlMember member, Object value, DependencyObject templatedParent)  
    at System.Windows.FrameworkTemplate.<>c__DisplayClass6.<LoadOptimizedTemplateContent>b__4(Object sender, XamlSetValueEventArgs setArgs)  
    at System.Xaml.XamlObjectWriter.OnSetValue(Object eventSender, XamlMember member, Object value)  
    at System.Xaml.XamlObjectWriter.Logic_ApplyPropertyValue(ObjectWriterContext ctx, XamlMember prop, Object value, Boolean onParent)  
    at System.Xaml.XamlObjectWriter.Logic_DoAssignmentToParentProperty(ObjectWriterContext ctx)  
    at System.Xaml.XamlObjectWriter.Logic_AssignProvidedValue(ObjectWriterContext ctx)  
    at System.Xaml.XamlObjectWriter.WriteEndObject()  
    at System.Xaml.XamlWriter.WriteNode(XamlReader reader)  
    at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)  
  InnerException: null

最佳答案

我会大胆猜测并建议您不要使用调用:只需从您所在的位置调用session.Open

我这么说是因为 - 如果您的 session 对象具有线程亲和性 - 您只是在当前线程上创建了它,因此 Open 调用需要在同一个线程上。您的 Invoke 可能会将调用推送到其他地方。

或者,可能是其他一些代码导致了问题。如果是这种情况,那么您可以改为尝试在任何调度程序线程上创建对象:

Session session = null;
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal,
    (Action)(() => { 
                     session = new ThirdPartyTool.Session();
                     session.Open(view);
                   } ));

关于c# - 调用线程无法访问此对象,因为另一个线程拥有它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16979885/

相关文章:

java - playframework 在 Globaj.java 对象内调用 onError 方法

javascript 将字符串作为函数调用

c# - 开发始终在桌面上的 Windows 10 小部件应用程序

c# - MVVM 在选择更改时调用异步方法

c# - 将c#连接到SQL服务器的教程

c# - 如何为 WPF TreeView 设置 DataTemplate 以显示列表的所有元素?

wpf - MVVM中驱动视觉状态的正确方法

wcf - 从其 URI (http ://ip:port/Service1. svc?WSDL) 动态调用 WCF 服务

c# - 为您的应用程序获取新的 Facebook 点赞流

c# - Caliburn.Micro 中的用户控件