{"record":{"id":"ff9ed5a2813dd1d5","repo":"stride3d/stride","slug":"this-workprogressviewmodel-is-already-associated-to-a","errorCode":null,"errorMessage":"This WorkProgressViewModel is already associated to a progress window","messagePattern":"This WorkProgressViewModel is already associated to a progress window","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Core.Assets.Editor/ViewModel/Progress/WorkProgressViewModel.cs","lineNumber":225,"sourceCode":"            switch (KeepOpen)\n            {\n                case KeepOpen.Never:\n                    return false;\n                case KeepOpen.OnWarningsOrErrors:\n                    return Log.HasWarnings || Log.HasErrors;\n                case KeepOpen.OnErrors:\n                    return Log.HasErrors;\n                case KeepOpen.Always:\n                    return true;\n                default:\n                    throw new ArgumentOutOfRangeException();\n            }\n        }\n\n        internal void NotifyWindowWillOpen()\n        {\n            if (windowWillOpen)\n                throw new InvalidOperationException(\"This WorkProgressViewModel is already associated to a progress window\");\n\n            windowWillOpen = true;\n        }\n\n        internal void NotifyWindowClosed()\n        {\n            workProgressClosed.TrySetResult(0);\n        }\n\n        /// <summary>\n        /// Helper method to raise event.\n        /// </summary>\n        /// <param name=\"handler\">The event handler to raise.</param>\n        private void RaiseEvent(EventHandler<WorkProgressNotificationEventArgs> handler)\n        {\n            handler?.Invoke(this, new WorkProgressNotificationEventArgs(this));\n        }\n","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Core.Assets.Editor/ViewModel/Progress/WorkProgressViewModel.cs#L207-L243","documentation":"NotifyWindowWillOpen marks a WorkProgressViewModel as bound to a progress window. If the method is called when windowWillOpen is already true, the library throws InvalidOperationException because a single view model cannot be associated with more than one window. ShowProgressWindow calls this internally when opening a window for the view model.","triggerScenarios":"Calling ShowProgressWindow (or NotifyWindowWillOpen directly) a second time on the same WorkProgressViewModel instance without the previous window having been closed (NotifyWindowClosed called).","commonSituations":"Launching two progress dialogs for the same long-running view model, e.g. re-showing progress for an already displayed operation, or reusing a cached view model across concurrent editor operations.","solutions":["Create a new WorkProgressViewModel for each progress window instead of reusing an instance.","Ensure the previous window is closed so NotifyWindowClosed resets windowWillOpen before reopening.","Track whether the window is already open and skip ShowProgressWindow if so.","Catch InvalidOperationException to detect double-open attempts and no-op."],"exampleFix":"// before\nif (progressViewModel == null)\n    progressViewModel = new WorkProgressViewModel(...);\nprogressViewModel.ShowProgressWindow();\n// after\nif (progressViewModel == null)\n    progressViewModel = new WorkProgressViewModel(...);\nelse if (progressViewModel.WorkDone)\n    progressViewModel = new WorkProgressViewModel(...);\nprogressViewModel.ShowProgressWindow();","handlingStrategy":"validation","validationCode":"if (progressViewModel.IsWindowOpen) return; // skip opening a second window","typeGuard":null,"tryCatchPattern":"try { vm.ShowProgressWindow(); }\ncatch (InvalidOperationException) { /* window already open; reuse it */ }","preventionTips":["One WorkProgressViewModel per window","Always close windows through NotifyWindowClosed paths","Never reuse finished view models for new operations"],"tags":["csharp","viewmodel","window","double-open"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}