Как отладить эту ошибку, когда ни один из моего кода не появляется в стеке? - PullRequest
4 голосов
/ 03 сентября 2010

Иногда я получаю следующую ошибку в моем приложении:

Невозможно использовать объект DependencyObject, принадлежащий другому потоку, чем его родительский Freezable

Я знаю, как решить эту ошибку, но в этом случае я не знаю , где это происходит, поэтому я не знаю, что исправить ... Трассировка стека исключений содержит только Код .NET Framework, а не мой код (кроме метода Main):

   at System.Windows.Freezable.EnsureConsistentDispatchers(DependencyObject owner, DependencyObject child)
   at System.Windows.Freezable.OnFreezablePropertyChanged(DependencyObject oldValue, DependencyObject newValue, DependencyProperty property)
   at System.Windows.Freezable.OnFreezablePropertyChanged(DependencyObject oldValue, DependencyObject newValue)
   at System.Windows.Media.RenderData.PropagateChangedHandler(EventHandler handler, Boolean adding)
   at System.Windows.UIElement.RenderClose(IDrawingContent newContent)
   at System.Windows.Media.VisualDrawingContext.CloseCore(RenderData renderData)
   at System.Windows.Media.RenderDataDrawingContext.DisposeCore()
   at System.Windows.Media.DrawingContext.System.IDisposable.Dispose()
   at System.Windows.Media.RenderDataDrawingContext.Close()
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at MS.Internal.Helper.ArrangeElementWithSingleChild(UIElement element, Size arrangeSize)
   at System.Windows.Controls.ContentPresenter.ArrangeOverride(Size arrangeSize)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.Controls.WrapPanel.arrangeLine(Double v, Double lineV, Int32 start, Int32 end, Boolean useItemU, Double itemU)
   at System.Windows.Controls.WrapPanel.ArrangeOverride(Size finalSize)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at MS.Internal.Helper.ArrangeElementWithSingleChild(UIElement element, Size arrangeSize)
   at System.Windows.Controls.ItemsPresenter.ArrangeOverride(Size arrangeSize)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.Controls.Border.ArrangeOverride(Size finalSize)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.Controls.Control.ArrangeOverride(Size arrangeBounds)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.Controls.Border.ArrangeOverride(Size finalSize)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.Controls.Grid.ArrangeOverride(Size arrangeSize)
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
   at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at MyApplication.App.Main() in E:\MyApplication\MyApplication\obj\Debug\App.g.cs:line 0
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Как я могу отследить причину этой ошибки? Поскольку приложение довольно сложное, ручная проверка всего кода, который может выполняться в другом потоке, на самом деле не вариант ...

Любой совет будет оценен!

Ответы [ 3 ]

1 голос
/ 03 сентября 2010

ОК, я наконец нашел решение ...

В одной из моих ViewModels я загружал список кистей из ресурсов темы. В некоторых ситуациях эта ViewModel использовалась из рабочего потока. Я предположил, что Freezables, определенные в словарях ресурсов XAML, были неявно заморожены, но, очевидно, это не так ... Поэтому мне просто нужно было явно заморозить их, и это решило проблему.

1 голос
/ 03 сентября 2010

Вы добавляете некоторые элементы управления UI динамически в обработчик DOwork фонового работника?

0 голосов
/ 03 сентября 2010

Вы пробовали Reflector Pro (есть 14-дневная пробная версия)? Вы можете попросить его сгенерировать отладочную информацию для WindowsBase.dll (где живет Freezable). Затем вы можете поместить точку останова в часть then оператора if в EnsureConsistentDispatchers. Это должно сказать вам, какие DependencyObjects участвуют.

Вы создаете объекты DependencyObject в другом потоке, отличном от потока GUI? Может быть, в методе обратного вызова?

...