{"record":{"id":"b3a16dd24790651b","repo":"dotnet/reactive","slug":"disposescheduler","errorCode":null,"errorMessage":"disposeScheduler","messagePattern":"disposeScheduler","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/SubscribeOn.cs","lineNumber":29,"sourceCode":"    {\n        public static IAsyncObservable<TSource> SubscribeOn<TSource>(this IAsyncObservable<TSource> source, IAsyncScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return SubscribeOn(source, scheduler, scheduler);\n        }\n\n        public static IAsyncObservable<TSource> SubscribeOn<TSource>(this IAsyncObservable<TSource> source, IAsyncScheduler subscribeScheduler, IAsyncScheduler disposeScheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (subscribeScheduler == null)\n                throw new ArgumentNullException(nameof(subscribeScheduler));\n            if (disposeScheduler == null)\n                throw new ArgumentNullException(nameof(disposeScheduler));\n\n            return CreateAsyncObservable<TSource>.From(\n                source,\n                (subscribeScheduler, disposeScheduler),\n                static async (source, state, observer) =>\n                {\n                    var m = new SingleAssignmentAsyncDisposable();\n                    var d = new SerialAsyncDisposable();\n\n                    await d.AssignAsync(m).ConfigureAwait(false);\n\n                    var scheduled = await state.subscribeScheduler.ScheduleAsync(async ct =>\n                    {\n                        var subscription = await source.SubscribeSafeAsync(observer).RendezVous(state.subscribeScheduler, ct);\n\n                        var scheduledDispose = AsyncDisposable.Create(async () =>\n                        {\n                            await state.disposeScheduler.ScheduleAsync(async _ =>","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/SubscribeOn.cs#L11-L47","documentation":"SubscribeOn(source, subscribeScheduler, disposeScheduler) validates the dispose scheduler last. A null disposeScheduler throws ArgumentNullException(\"disposeScheduler\") because resource disposition must be scheduled onto it.","triggerScenarios":"Calling source.SubscribeOn(subscribeScheduler, null) — often when the caller believes disposal reuses the subscribe scheduler, or the dispose scheduler variable was never assigned.","commonSituations":"Simplifying a call by dropping an argument; config lacking a separate dispose scheduler; refactoring from the single-scheduler overload leaving the second parameter null.","solutions":["Use the single-scheduler overload SubscribeOn(source, scheduler) if both phases should use one scheduler.","Pass a valid dispose scheduler instance explicitly.","Fix whatever returns/assigns null to the dispose scheduler."],"exampleFix":"// before\nvar obs = source.SubscribeOn(subscribeScheduler, null);\n// after\nvar obs = source.SubscribeOn(subscribeScheduler); // same scheduler for subscribe and dispose","handlingStrategy":"validation","validationCode":"if (disposeScheduler == null)\n    disposeScheduler = subscribeScheduler; // or AsyncScheduler.DefaultScheduler","typeGuard":"bool HasDisposeScheduler(IAsyncScheduler? d) => d is not null;","tryCatchPattern":"try\n{\n    var obs = source.SubscribeOn(subscribeScheduler, disposeScheduler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"disposeScheduler\")\n{\n    logger.LogError(ex, \"Null dispose scheduler\");\n    obs = source.SubscribeOn(subscribeScheduler);\n}","preventionTips":["If no separate dispose scheduler is needed, use SubscribeOn(source, scheduler).","Initialize dispose scheduler fields together with subscribe scheduler fields.","Document config keys for both schedulers and fail fast at startup if missing."],"tags":["argument-null","scheduler","dispose","async-rx"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}