{"record":{"id":"5d5a206d43669213","repo":"dotnet/wpf","slug":"sr-collectionview-missingsynchronizationcallback","errorCode":null,"errorMessage":"SR.CollectionView_MissingSynchronizationCallback","messagePattern":"SR\\.CollectionView_MissingSynchronizationCallback","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/ViewManager.cs","lineNumber":394,"sourceCode":"                // target gets GC'd\n                object target = callback.Target;\n                _callbackTarget = (target != null) ? new WeakReference(target) : ViewManager.StaticWeakRef;\n            }\n        }\n\n        public bool IsSynchronized\n        {\n            get { return _context != null || _callbackMethod != null; }\n        }\n\n        public void AccessCollection(IEnumerable collection, Action accessMethod, bool writeAccess)\n        {\n            if (_callbackMethod != null)\n            {\n                // make sure the callback's target is still available\n                object target = _callbackTarget.Target;\n                if (target == null)\n                    throw new InvalidOperationException(SR.Format(SR.CollectionView_MissingSynchronizationCallback, collection));\n\n                // invoke the callback\n                if (_callbackTarget == ViewManager.StaticWeakRef)\n                    target = null;          // static method\n\n                WeakReference wrContext = _context as WeakReference;\n                object context = (wrContext != null) ? wrContext.Target : _context;\n                _callbackMethod.Invoke(target, new object[] { collection, context, accessMethod, writeAccess });\n            }\n            else if (_context != null)\n            {\n                lock (_context)\n                {\n                    accessMethod();\n                }\n            }\n            else\n            {","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/ViewManager.cs#L376-L412","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n// background thread:\nmyView.Refresh(); // view's creator already collected\n// after\nApplication.Current.Dispatcher.Invoke(() => myView.Refresh());","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { Dispatcher.Invoke(() => view.Refresh()); }\ncatch (InvalidOperationException) { view = (ICollectionView)CollectionViewSource.GetDefaultView(liveSource); /* recreate */ }","preventionTips":["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"],"tags":["wpf","collectionview","threading","dispatcher"],"backgroundTag":"thread-interrupted","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}