我有一个随机抛出异常的大型应用程序。 此异常没有再现路径,日志中没有明确的堆栈跟踪:
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作为源。
答案 0 :(得分:1)
您可以尝试使用
BindingOperations.EnableCollectionSynchronization(myCollection, myLockObject);
至少应该消除所有与线程相关的问题。 这是从.NET 4.5开始提供的,以防您仍在使用较低版本。