{"record":{"id":"869eac2172f751c5","repo":"stride3d/stride","slug":"effectsystem-has-been-disposed-this-effect-compilation-has","errorCode":null,"errorMessage":"EffectSystem has been disposed. This Effect compilation has been cancelled.","messagePattern":"EffectSystem has been disposed\\. This Effect compilation has been cancelled\\.","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Rendering/Rendering/EffectSystem.cs","lineNumber":188,"sourceCode":"        }\n\n        // TODO: THIS IS JUST A WORKAROUND, REMOVE THIS\n\n        private static void CheckResult(LoggerResult compilerResult)\n        {\n            if (compilerResult.HasErrors)\n            {\n                throw new InvalidOperationException(\"Could not compile shader. See error messages: \" + compilerResult.ToText());\n            }\n        }\n\n        private Effect CreateEffect(string effectName, EffectBytecodeCompilerResult effectBytecodeCompilerResult, CompilerResults compilerResult)\n        {\n            Effect effect;\n            lock (cachedEffects)\n            {\n                if (!isInitialized)\n                    throw new ObjectDisposedException(nameof(EffectSystem), \"EffectSystem has been disposed. This Effect compilation has been cancelled.\");\n\n                if (effectBytecodeCompilerResult.CompilationLog.HasErrors)\n                {\n                    // Unregister result\n                    // TODO: Should we keep it so that failure never change?\n                    if (earlyCompilerCache.TryGetValue(effectName, out List<CompilerResults> effectCompilerResults))\n                    {\n                        effectCompilerResults.Remove(compilerResult);\n                    }\n                }\n\n                CheckResult(effectBytecodeCompilerResult.CompilationLog);\n\n                var bytecode = effectBytecodeCompilerResult.Bytecode\n                    ?? throw new InvalidOperationException(\"EffectCompiler returned no shader and no compilation error.\");\n\n                if (!cachedEffects.TryGetValue(bytecode, out effect))\n                {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Rendering/Rendering/EffectSystem.cs#L170-L206","documentation":"EffectSystem.CreateEffect aborts with ObjectDisposedException if the system was disposed while an effect compilation was in flight. The isInitialized check under the cachedEffects lock detects shutdown that happened during asynchronous compilation.","triggerScenarios":"Calling LoadEffect (or awaiting a pending effect task) after GraphicsDevice/EffectSystem was disposed, e.g. during scene teardown or application shutdown while shaders still compile in the background.","commonSituations":"Loading scenes/materials asynchronously and disposing the device when a window closes; race between background compilation and Dispose.","solutions":["Ensure all LoadEffect calls complete before disposing the GraphicsDevice/EffectSystem.","Await pending effect compilation tasks before shutdown.","Recreate the EffectSystem (re-initialize) if you need to load effects after disposal.","Guard application shutdown order: release materials/effects first, then the device."],"exampleFix":"// before\ndevice.Dispose();\nvar effect = effectSystem.LoadEffect(\"MyEffect\"); // throws\n// after\nawait loadTask; // finish compilations\neffectSystem.Dispose();\ndevice.Dispose();","handlingStrategy":"try-catch","validationCode":"// Check before requesting an effect\nif (!effectSystem.IsInitialized) throw new InvalidOperationException(\"EffectSystem disposed; cannot load effects\");","typeGuard":"bool CanLoadEffects(EffectSystem s) => s != null && s.IsInitialized;","tryCatchPattern":"try { var effect = effectSystem.LoadEffect(\"MyEffect\"); }\ncatch (ObjectDisposedException)\n{\n    // EffectSystem was disposed mid-compilation; re-initialize or abort the load\n}","preventionTips":["Await all LoadEffect tasks before disposing GraphicsDevice.","Order shutdown: cancel loads -> dispose effects/materials -> dispose device.","Avoid fire-and-forget scene loads during window close."],"tags":["stride","effect-system","disposed","race-condition"],"backgroundTag":"use-after-dispose","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}