wpf 调用线程无法访问此对象,因为其他线程拥有它

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16979885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:57:12  来源:igfitidea点击:

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

c#wpfinvokeinvalidoperationexception

提问by Em1

I am using a third party tool in which I get an InvalidOperationException (actually, in the end this occurs in PresentationFramework.dll):

我正在使用第三方工具,在该工具中我收到了 InvalidOperationException(实际上,这最终发生在 PresentationFramework.dll 中):

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

调用线程无法访问此对象,因为其他线程拥有它。

I tried any kind of variations using Invoke, including BeginInvoke, but nothing changes.

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

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

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

When using Google I only find "solutions" that suggest to use Invoke. Well, I do use Invoke.
Other questions and their respective answer here on stackoverflow didn't help either.

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

What can I still do in order to track down the actual cause?

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



Edit: I had another look into the thread window and the full call stack is in the main thread. AFAIK, this indicates the Invoke is superfluous.

编辑:我再次查看了线程窗口,完整的调用堆栈位于主线程中。AFAIK,这表明调用是多余的。



Edit2:
The error isn't raised directly on calling open. The ThirdPartyTool initializes a list box and when measuring this list box the error occurs in the presentation framework:

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

enter image description here

在此处输入图片说明

The actual exception is wrapped into an XamlParseException. The full exception detail:

实际异常被包装到 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

回答by Dan Puzey

I'd hazard a guess and suggest that you don'tuse invoke: just call session.Openfrom where you are.

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

I say that because - if your sessionobject has thread affinity - you've just created it on whatever the current thread is, and so the Opencall needs to be on the same thread. Your Invokeis potentially pushing the call elsewhere.

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

Alternatively, it could be that some other code is causing the problem. If that's the case then you could instead try this to createthe object on whatever the dispatcher thread is:

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

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

回答by Em1

It turned out that an image which was off my radar screen was causing the issue. Once we called Freeze, the issue disappeared.

事实证明,我的雷达屏幕上的图像导致了这个问题。一旦我们打电话Freeze,问题就消失了。