{"record":{"id":"d7bbd162f44519d2","repo":"dotnet/reactive","slug":"scheduler-fromeventpattern","errorCode":null,"errorMessage":"scheduler","messagePattern":"scheduler","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs","lineNumber":25,"sourceCode":"using System.Reactive.Disposables;\nusing System.Reflection;\nusing System.Runtime.ExceptionServices;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler) => FromEventPattern(addHandler, removeHandler, GetSchedulerForCurrentContext());\n\n        public static IAsyncObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IAsyncScheduler scheduler)\n        {\n            if (addHandler == null)\n                throw new ArgumentNullException(nameof(addHandler));\n            if (removeHandler == null)\n                throw new ArgumentNullException(nameof(removeHandler));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return FromEvent<EventHandler, object, EventArgs>(\n                action => new EventHandler((o, e) => action(o, e)),\n                addHandler,\n                removeHandler,\n                scheduler).Select(t => new EventPattern<object>(t.arg1, t.arg2));\n        }\n\n        public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) => FromEventPattern<TDelegate, TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());\n\n        public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)\n        {\n            if (addHandler == null)\n                throw new ArgumentNullException(nameof(addHandler));\n            if (removeHandler == null)\n                throw new ArgumentNullException(nameof(removeHandler));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs#L7-L43","documentation":"System.ArgumentNullException with param name 'scheduler'. This overload of FromEventPattern takes an explicit IAsyncScheduler to control where subscription/dispatch runs, and the null check throws immediately if scheduler is null. The library does not fall back to a default in this overload by design.","triggerScenarios":"Calling FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IAsyncScheduler scheduler) with a null scheduler, e.g. FromEventPattern(h => e.AddHandler(h), h => e.RemoveHandler(h), null) or passing a scheduler variable that was never initialized.","commonSituations":"A scheduler obtained from a factory or DI container is null (failed resolution), or the developer meant to call the two-argument overload (which uses GetSchedulerForCurrentContext()) but included a trailing null.","solutions":["Pass a valid IAsyncScheduler instance, e.g. AsyncScheduler.Default or your configured test scheduler.","Drop the third argument entirely to use the overload that resolves the scheduler from the current context.","If the scheduler comes from DI/configuration, verify it is registered and non-null before the call.","Guard with an ArgumentNullException.ThrowIfNull-style check at your call site to get a clearer stack trace."],"exampleFix":"// before\nvar obs = AsyncObservable.FromEventPattern(\n    h => target.Something += h,\n    h => target.Something -= h,\n    null);\n// after\nvar obs = AsyncObservable.FromEventPattern(\n    h => target.Something += h,\n    h => target.Something -= h,\n    AsyncScheduler.Default);","handlingStrategy":"validation","validationCode":"if (scheduler == null) scheduler = AsyncScheduler.Default; // or omit the parameter entirely","typeGuard":"static bool HasScheduler(IAsyncScheduler scheduler) => scheduler != null;","tryCatchPattern":"try\n{\n    var obs = AsyncObservable.FromEventPattern(add, remove, scheduler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"scheduler\")\n{\n    // fall back or fix scheduler initialization\n}","preventionTips":["Prefer the 2-argument overload unless a specific scheduler is required.","Resolve schedulers from DI and validate at composition time.","Initialize test schedulers before building observable pipelines.","Never pass a literal null as the scheduler argument."],"tags":["argument-null","scheduler","reactive-extensions","dotnet"],"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"}