{"record":{"id":"f888fa8b690819be","repo":"dotnet/reactive","slug":"dispatcher-coredispatcherobservable","errorCode":null,"errorMessage":"dispatcher","messagePattern":"dispatcher","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/CoreDispatcherObservable.cs","lineNumber":178,"sourceCode":"        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"dispatcher\">Dispatcher whose associated message loop is used to perform subscription and unsubscription actions on.</param>\n        /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified dispatcher.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"dispatcher\"/> is null.</exception>\n        /// <remarks>\n        /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified dispatcher.\n        /// In order to invoke observer callbacks on the specified dispatcher, e.g. to render results in a control, use <see cref=\"CoreDispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, CoreDispatcher)\"/>.\n        /// </remarks>\n        public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, CoreDispatcher dispatcher)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (dispatcher == null)\n            {\n                throw new ArgumentNullException(nameof(dispatcher));\n            }\n\n            return Synchronization.SubscribeOn(source, new CoreDispatcherScheduler(dispatcher));\n        }\n\n        /// <summary>\n        /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified dispatcher.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"dispatcher\">Dispatcher whose associated message loop is used to perform subscription and unsubscription actions on.</param>\n        /// <param name=\"priority\">Priority to schedule work items at.</param>\n        /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified dispatcher.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"dispatcher\"/> is null.</exception>\n        /// <remarks>\n        /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified dispatcher.\n        /// In order to invoke observer callbacks on the specified dispatcher, e.g. to render results in a control, use <see cref=\"CoreDispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, CoreDispatcher, CoreDispatcherPriority)\"/>.\n        /// </remarks>","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/CoreDispatcherObservable.cs#L160-L196","documentation":"SubscribeOn(source, dispatcher) throws ArgumentNullException when the dispatcher parameter is null. The dispatcher is required to construct the CoreDispatcherScheduler used to marshal subscription (and disposal) work onto the UI thread. The library validates both arguments eagerly at call time.","triggerScenarios":"Calling observable.SubscribeOn(null), or passing a dispatcher obtained from a null object — e.g. Window.Current is null in background threads/non-UI contexts, or a control's Dispatcher property read after the element was detached in edge cases.","commonSituations":"Calling SubscribeOn from a background thread where CoreWindow/Window.Current is unavailable; caching a Window reference that is null when the app runs in a hosted/background context; accidentally swapping argument order or passing an uninitialized field.","solutions":["Capture the dispatcher on the UI thread at startup (e.g. during OnLaunched) and pass that cached instance instead of resolving it at call time.","Use CoreDispatcherScheduler.Current only on UI threads; on background threads capture the UI dispatcher once and store it in a service.","Validate before calling: if (dispatcher == null) throw or fall back to SubscribeOn(TaskPoolScheduler.Default).","Check that the object whose Dispatcher you pass is not null itself (null dependencyObject.Dispatcher is impossible here since the argument is typed CoreDispatcher, but passing null literals happens in refactors)."],"exampleFix":"// before\nsource.SubscribeOn(Window.Current?.Dispatcher) // null on background thread\n// after\nprivate static CoreDispatcher _uiDispatcher;\npublic static void Init(CoreDispatcher d) => _uiDispatcher = d; // called on UI thread\nsource.SubscribeOn(_uiDispatcher)","handlingStrategy":"validation","validationCode":"if (dispatcher == null)\n    throw new InvalidOperationException(\"Capture the UI dispatcher on the UI thread before calling SubscribeOn\");\nsource.SubscribeOn(dispatcher).Subscribe(handler);","typeGuard":"bool HasDispatcher(CoreDispatcher d) => d != null;","tryCatchPattern":"try { source.SubscribeOn(dispatcher).Subscribe(handler); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"dispatcher\")\n{ source.SubscribeOn(DefaultScheduler.Instance).Subscribe(handler); }","preventionTips":["Capture Window.Current.Dispatcher once during app startup, not at call time.","Never resolve Window.Current from background/thread-pool threads.","Inject the dispatcher as a service rather than reaching for globals.","Prefer SubscribeOn(dispatcher) over object-derived overloads to make the null point explicit."],"tags":["argumentnull","winrt","reactive-extensions","dispatcher","null-dispatcher"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}