dotnet/wpf · error · InvalidOperationException
SR.CompatibilityPreferencesSealed…
Error message
SR.CompatibilityPreferencesSealed (ReuseDispatcherSynchronizationContextInstance, BaseCompatibilityPreferences)
What it means
BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance can only be set before WPF seals the compatibility preferences (which happens once the Application/Dispatcher infrastructure initializes). Setting it afterwards throws InvalidOperationException with SR.CompatibilityPreferencesSealed naming this property. The setter is guarded by a lock and an _isSealed flag.
Solutions
- Move the assignment to the earliest point in the process, e.g. before creating the Application object (in Main or a module initializer).
- Ensure all BaseCompatibilityPreferences writes happen on one thread before any WPF type from PresentationFramework is touched.
- In tests, run each preference-setting test in its own process/appdomain, or read rather than write preferences after init.
Example fix
// before
protected override void OnStartup(StartupEventArgs e)
{
BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance = true;
...
}
// after
public static void Main()
{
BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance = true;
var app = new App();
app.Run();
} Defensive patterns
Strategy: validation
Validate before calling
// Call this in Main before any WPF type is used:
void ConfigureCompatPreferences()
{
// must be the first WPF touch point in the process
BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance = true;
} Try / catch
try { BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance = v; }
catch (InvalidOperationException) { /* already sealed: setting ignored — log and continue */ } Prevention
- Set all BaseCompatibilityPreferences before constructing Application.
- Keep them in one static pre-init location (Main or module initializer).
- Never set them from event handlers, libraries, or tests after WPF init.
When it happens
Trigger: Assigning BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance = true/false anywhere after the Application has been constructed or a Dispatcher has started (e.g. in App.OnStartup after base init, or on a background thread late in app lifetime).
Common situations: Moving compatibility settings out of the static Main/PreStart phase during a refactor; setting them in a unit test after a previous test already touched WPF; setting them inside event handlers.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.CompatibilityPreferencesSealed…
- SR.CompatibilityPreferencesSealed…
- Current DocumentSequence, FixedDocument, or FixedPage not…
- ElementNotAvailableException
- IAmbientProvider
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/320f2e753f3b0f1a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/BaseCompatibilityPreferences.cs:84
///
/// 2) Some task-parallel implementations implement potentially
/// cross-thread completions by callling
/// SynchronizationContext.Post and Wait() and an event to be
/// signaled. If this was not a true cross-thread completion,
/// but rather just two seperate instances of
/// DispatcherSynchronizationContext for the same thread, this
/// would result in a deadlock.
/// </summary>
public static bool ReuseDispatcherSynchronizationContextInstance
{
get { return _reuseDispatcherSynchronizationContextInstance; }
set
{
lock (_lockObject)
{
if (_isSealed)
{
throw new InvalidOperationException(SR.Format(SR.CompatibilityPreferencesSealed, "ReuseDispatcherSynchronizationContextInstance", "BaseCompatibilityPreferences"));
}
_reuseDispatcherSynchronizationContextInstance = value;
}
}
}
internal static bool GetReuseDispatcherSynchronizationContextInstance()
{
Seal();
return ReuseDispatcherSynchronizationContextInstance;
}
#if NETFX && !NETCOREAPP
private static bool _reuseDispatcherSynchronizationContextInstance = BinaryCompatibility.TargetsAtLeast_Desktop_V4_5 ? false : true;
#elif NETCOREAPP
private static bool _reuseDispatcherSynchronizationContextInstance = false;View on GitHub (pinned to 81131a70a4)