{"record":{"id":"b7e058505a606575","repo":"dotnet/reactive","slug":"argumentnullexception-dispatcher","errorCode":null,"errorMessage":"ArgumentNullException: dispatcher","messagePattern":"ArgumentNullException: dispatcher","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/CoreDispatcherObservable.cs","lineNumber":39,"sourceCode":"\n        /// <summary>\n        /// Wraps the source sequence in order to run its observer callbacks 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 notify observers on.</param>\n        /// <returns>The source sequence whose observations happen on the specified dispatcher.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"dispatcher\"/> is null.</exception>\n        public static IObservable<TSource> ObserveOn<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.ObserveOn(source, new CoreDispatcherScheduler(dispatcher));\n        }\n\n        /// <summary>\n        /// Wraps the source sequence in order to run its observer callbacks 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 notify observers on.</param>\n        /// <param name=\"priority\">Priority to schedule work items at.</param>\n        /// <returns>The source sequence whose observations happen on the specified dispatcher.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"dispatcher\"/> is null.</exception>\n        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, CoreDispatcher dispatcher, CoreDispatcherPriority priority)\n        {\n            if (source == null)\n            {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/CoreDispatcherObservable.cs#L21-L57","documentation":"ObserveOn(source, CoreDispatcher) also validates the dispatcher and throws ArgumentNullException('dispatcher') when it is null. The dispatcher identifies the thread on which notifications are delivered, so it is required.","triggerScenarios":"Calling source.ObserveOn(null) — common when Window.Current/CoreWindow is not available (e.g. code running in a background thread, a host window closed, or app suspending).","commonSituations":"UWP apps accessing CoreDispatcher from a non-UI thread where Window.Current is null; sharing a cached dispatcher field that was disposed or never initialized; unit tests without a dispatcher.","solutions":["Obtain the dispatcher correctly: Window.Current.Dispatcher (UI thread) or CoreWindow.GetForCurrentThread().Dispatcher.","Cache the dispatcher while on the UI thread (e.g. in App startup) rather than fetching it from a background thread.","Use ObserveOnDispatcher()/ObserveOnCoreDispatcher() when you simply want the current window's dispatcher."],"exampleFix":"// before\nCoreDispatcher dispatcher = Window.Current?.Dispatcher; // null off UI thread\nstream.ObserveOn(dispatcher);\n// after\nvar dispatcher =CoreApplication.MainView.CoreWindow.Dispatcher; // or capture on UI thread at startup\nstream.ObserveOn(dispatcher);","handlingStrategy":"validation","validationCode":"var dispatcher = Window.Current?.Dispatcher;\nif (dispatcher is null)\n{\n    // not on the UI thread — capture earlier or fall back\n    subscribeOnDefault = true;\n}\nelse\n{\n    stream.ObserveOn(dispatcher).Subscribe(OnNext);\n}","typeGuard":"static bool HasDispatcher(CoreDispatcher d) => d is not null;","tryCatchPattern":"try\n{\n    stream.ObserveOn(dispatcher).Subscribe(OnNext);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"dispatcher\")\n{\n    log.Warn(\"CoreDispatcher unavailable (off UI thread or window closed).\");\n}","preventionTips":["Capture Window.Current.Dispatcher once at app startup while on the UI thread.","Never fetch the dispatcher from background threads where Window.Current is null.","Prefer ObserveOnCoreDispatcher() on the UI thread to avoid manual dispatcher handling."],"tags":["null-check","argument-validation","rx","uwp","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"}