{"record":{"id":"0d9f63959180b7ef","repo":"dotnet/wpf","slug":"sr-compatibilitypreferencessealed-0d9f63","errorCode":null,"errorMessage":"SR.CompatibilityPreferencesSealed (InlineDispatcherSynchronizationContextSend, BaseCompatibilityPreferences)","messagePattern":"SR\\.CompatibilityPreferencesSealed \\(InlineDispatcherSynchronizationContextSend, BaseCompatibilityPreferences\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/BaseCompatibilityPreferences.cs","lineNumber":185,"sourceCode":"        ///     posts through the Dispatcher queue.\n        ///\n        ///     In WPF 4.5 we are changing the behavior such that calling\n        ///     SynchronizationContext.Send on the same thread, will not post\n        ///     through the Dispatcher queue, but rather invoke the delegate\n        ///     more directly.  The cross-thread behavior does not change.\n        ///\n        ///     This is, of course, an observable change in behavior.\n        /// </summary>\n        public static bool InlineDispatcherSynchronizationContextSend\n        {\n            get { return _inlineDispatcherSynchronizationContextSend; }\n            set\n            {\n                lock (_lockObject)\n                {\n                    if (_isSealed)\n                    {\n                        throw new InvalidOperationException(SR.Format(SR.CompatibilityPreferencesSealed, \"InlineDispatcherSynchronizationContextSend\", \"BaseCompatibilityPreferences\"));\n                    }\n\n                    _inlineDispatcherSynchronizationContextSend = value;\n                }\n            }\n        }\n\n        internal static bool GetInlineDispatcherSynchronizationContextSend()\n        {\n            Seal();\n\n            return InlineDispatcherSynchronizationContextSend;\n        }\n\n#if NETFX && !NETCOREAPP\n        private static bool _inlineDispatcherSynchronizationContextSend = BinaryCompatibility.TargetsAtLeast_Desktop_V4_5 ? true : false;\n#elif NETCOREAPP\n        private static bool _inlineDispatcherSynchronizationContextSend = true;","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/BaseCompatibilityPreferences.cs#L167-L203","documentation":"BaseCompatibilityPreferences.InlineDispatcherSynchronizationContextSend may only be configured before WPF seals its compatibility preferences; after sealing, the setter throws InvalidOperationException with SR.CompatibilityPreferencesSealed naming this property. Sealing occurs when the WPF runtime initializes (first Application/Dispatcher use), so late writes are rejected.","triggerScenarios":"Assigning BaseCompatibilityPreferences.InlineDispatcherSynchronizationContextSubtitle/InlineDispatcherSynchronizationContextSend after the Dispatcher exists — e.g. from a Dispatcher.Invoke callback, an event handler, or second app-domain initialization.","commonSituations":"Toggling SynchronizationContext inline-send behavior to fix async timing bugs discovered in production and placing the fix in Startup; dynamic configuration loaded from a config file read after WPF init.","solutions":["Set the property at the very start of the process (Main/module initializer) before instantiating Application.","Read config synchronously before WPF initialization rather than lazily after startup.","If the setting must be conditional, compute the condition pre-init, not inside WPF callbacks."],"exampleFix":"// before\nprivate void OnLoaded(object s, RoutedEventArgs e)\n{\n    BaseCompatibilityPreferences.InlineDispatcherSynchronizationContextSend = true;\n}\n// after\npublic static void Main()\n{\n    BaseCompatibilityPreferences.InlineDispatcherSynchronizationContextSend = true;\n    new App().Run();\n}","handlingStrategy":"validation","validationCode":"// Runs only during pre-init:\nstatic class CompatPrefs\n{\n    [ModuleInitializer]\n    public static void Init() =>\n        BaseCompatibilityPreferences.InlineDispatcherSynchronizationContextSend = true;\n}","typeGuard":null,"tryCatchPattern":"try { BaseCompatibilityPreferences.InlineDispatcherSynchronizationContextSend = v; }\ncatch (InvalidOperationException) { /* sealed — apply at next process start instead */ }","preventionTips":["Use a module initializer or first line of Main for preference writes.","Grep the codebase for BaseCompatibilityPreferences writes and ensure they're pre-init.","Treat these settings as process-lifetime immutable."],"tags":["wpf","invalid-state","dispatcher","initialization-order"],"backgroundTag":"invalid-state-transition","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"}