{"record":{"id":"63be0cc3f08a4a89","repo":"dotnet/wpf","slug":"sr-itemcollectionshoulduseinnersyncroot","errorCode":null,"errorMessage":"SR.ItemCollectionShouldUseInnerSyncRoot","messagePattern":"SR\\.ItemCollectionShouldUseInnerSyncRoot","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemCollection.cs","lineNumber":749,"sourceCode":"            }\n        }\n\n        /// <summary>\n        ///     Returns an object to be used in thread synchronization.\n        /// </summary>\n        /// <exception cref=\"NotSupportedException\">\n        /// ItemCollection cannot provide a sync root for synchronization while\n        /// in ItemsSource mode.  Please use the ItemsSource directly to\n        /// get its sync root.\n        /// </exception>\n        object ICollection.SyncRoot\n        {\n            get\n            {\n                if (IsUsingItemsSource)\n                {\n                    // see discussion in XML comment above.\n                    throw new NotSupportedException(SR.ItemCollectionShouldUseInnerSyncRoot);\n                }\n\n                return _internalView.SyncRoot;\n            }\n        }\n\n        /// <summary>\n        ///     Gets a value indicating whether the IList has a fixed size.\n        ///     An ItemCollection can usually grow dynamically,\n        ///     this call will commonly return FixedSize = False.\n        ///     In ItemsSource mode, this call will return IsFixedSize = True.\n        /// </summary>\n        bool IList.IsFixedSize\n        {\n            get\n            {\n                return IsUsingItemsSource;\n            }","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemCollection.cs#L731-L767","documentation":"ItemCollection.SyncRoot throws NotSupportedException(SR.ItemCollectionShouldUseInnerSyncRoot) when the collection is in ItemsSource mode. In that mode the wrapper does not own the backing store, so locking on the wrapper's SyncRoot would synchronize on the wrong object; callers must lock the underlying collection's SyncRoot instead.","triggerScenarios":"Accessing itemsControl.Items.SyncRoot while IsUsingItemsSource is true (ItemsSource assigned to a collection).","commonSituations":"Multi-threaded code locking on Items.SyncRoot to serialize updates; refactoring code that worked with direct Items.Add into ItemsSource binding without updating the locking strategy.","solutions":["Lock on the underlying source collection's SyncRoot (or use its own synchronization) instead of Items.SyncRoot.","Prefer dispatching all collection mutations to the UI thread rather than locking.","Use a BindingOperations/CollectionView-safe pattern (e.g. lock the ObservableCollection's SyncRoot or a dedicated lock object you own)."],"exampleFix":"// before\nlock (itemsControl.Items.SyncRoot) { source.Add(x); }\n// after\nvar oc = (ObservableCollection<MyItem>)itemsControl.ItemsSource;\nlock (((ICollection)oc).SyncRoot) { oc.Add(x); }","handlingStrategy":"fallback","validationCode":"if (items.IsUsingItemsSource)\n{\n    var src = (ICollection)itemsControl.ItemsSource;\n    lock (src.SyncRoot) { /* mutate source */ }\n}","typeGuard":"static ICollection SourceCollection(ItemCollection c) => (ICollection)c.GetType().GetProperty(\"CollectionView\")?.GetValue(c);","tryCatchPattern":"try { return items.SyncRoot; }\ncatch (NotSupportedException) { return ((ICollection)itemsControl.ItemsSource).SyncRoot; }","preventionTips":["Never lock on Items.SyncRoot when ItemsSource is set","Prefer single-threaded UI access via Dispatcher instead of locking","Lock the source collection or a dedicated lock object"],"tags":["wpf","itemcollection","notsupportedexception","threading"],"backgroundTag":"unsupported-operation","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"}