没有堆栈跟踪的WPF崩溃

时间:2017-07-04 13:14:06

标签: c# wpf

我有一个随机抛出异常的大型应用程序。 此异常没有再现路径,日志中没有明确的堆栈跟踪:

AppDomain.CurrentDomain.UnhandledException System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Windows.Data.ListCollectionView.RestoreLiveShaping()
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
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, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
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 FullDownloadManager.App.Main()

正如您所看到的,这是一个并发问题,当UI线程刷新并遍历列表时,某些集合被更改。

问题在于找到它发生的位置,因为没有跟踪它发生的位置。

有没有人知道如何检测抛出此异常的位置?

谢谢,

更新 我正在审查我的程序集合的所有结果,我发现了一个有趣的场景可能是原因:

首先,我有一个与ObservableCollection绑定的CollectionViewSource

<CollectionViewSource x:Key="deviceViewSource" Source="{Binding ElementName=_this, Path=Devices}"
                          IsLiveGroupingRequested="True">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription Converter="{StaticResource deviceGroupConverter}" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

由于Source是Syncrhonized,它可能不是问题。请注意,我将LiveGrouping设置为true

现在这是有趣的部分:

<ItemsControl ItemsSource="{Binding Source={StaticResource deviceViewSource}, Path=Groups}"
    <ItemsControl.ItemTemplate>
            <DataTemplate>
                . . . 
                <ItemsControl ItemsSource="{Binding Items}" >
                      . . .
                </ItemsControl>
             </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

如果CollectionViewSource的不是线程安全的,我可能会遇到问题?

UPDATE2: 我确认问题出在CollectionViewSource和Groupping上。 由于我无法解决此问题,我的解决方案是手动分组和同步UI。

建议 BindingOperations.EnableCollectionSynchronization 可能会解决此问题,但我还没有尝试过。

无论如何,CollectionViewSource不是线程安全的,这很奇怪,甚至很难我使用ObservableCollection作为源。

1 个答案:

答案 0 :(得分:1)

您可以尝试使用

BindingOperations.EnableCollectionSynchronization(myCollection, myLockObject);

至少应该消除所有与线程相关的问题。 这是从.NET 4.5开始提供的,以防您仍在使用较低版本。