dotnet/wpf · error · InvalidOperationException
SR.CollectionView_MissingSynchronizationCallback
Error message
SR.CollectionView_MissingSynchronizationCallback
What it means
ViewManager.AccessCollection invokes a CollectionView's synchronization callback on the correct (UI/dispatcher) context. Before invoking, it dereferences the weak reference to the callback's target; if the target has been garbage collected, it throws InvalidOperationException(SR.CollectionView_MissingSynchronizationCallback).
Solutions
- Keep the CollectionView's owning context alive (store a strong reference) while background threads use it
- Route all cross-thread collection updates through Dispatcher.Invoke/BeginInvoke on the UI thread instead of touching the view directly
- Recreate the CollectionView (GetDefaultView) from a live source on the UI thread before use
- Bind via BindingOperations.EnableCollectionSynchronization for correct cross-thread access
Example fix
// before // background thread: myView.Refresh(); // view's creator already collected // after Application.Current.Dispatcher.Invoke(() => myView.Refresh());
Defensive patterns
Strategy: try-catch
Try / catch
try { Dispatcher.Invoke(() => view.Refresh()); }
catch (InvalidOperationException) { view = (ICollectionView)CollectionViewSource.GetDefaultView(liveSource); /* recreate */ } Prevention
- Use BindingOperations.EnableCollectionSynchronization for cross-thread collection updates
- Do not hold CollectionViews beyond their owning view's lifetime
- Route all view mutations through the UI Dispatcher
- Keep a strong reference to the view creator while background work is pending
When it happens
Trigger: A background thread accesses a CollectionView (e.g. Add/Remove/enumeration with cross-thread checks) after the object that created the view's synchronization callback has been collected; the weak _callbackTarget.Target returns null.
Common situations: Long-lived CollectionViews whose owning window/view was closed and collected but the view is still touched from worker threads; holding views in statics while their creators die.
Related errors
- SR.MultiThreadedCollectionChangeNotSupported
- Processing is disabled while the Dispatcher is in this…
- SR.ContextMenuInDifferentDispatcher
- SR.CurrentDispatcherNotFound
- SR.DispatcherHasShutdown
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5d5a206d43669213.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/ViewManager.cs:394
// target gets GC'd
object target = callback.Target;
_callbackTarget = (target != null) ? new WeakReference(target) : ViewManager.StaticWeakRef;
}
}
public bool IsSynchronized
{
get { return _context != null || _callbackMethod != null; }
}
public void AccessCollection(IEnumerable collection, Action accessMethod, bool writeAccess)
{
if (_callbackMethod != null)
{
// make sure the callback's target is still available
object target = _callbackTarget.Target;
if (target == null)
throw new InvalidOperationException(SR.Format(SR.CollectionView_MissingSynchronizationCallback, collection));
// invoke the callback
if (_callbackTarget == ViewManager.StaticWeakRef)
target = null; // static method
WeakReference wrContext = _context as WeakReference;
object context = (wrContext != null) ? wrContext.Target : _context;
_callbackMethod.Invoke(target, new object[] { collection, context, accessMethod, writeAccess });
}
else if (_context != null)
{
lock (_context)
{
accessMethod();
}
}
else
{View on GitHub (pinned to 81131a70a4)