// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. using System.Reactive.Disposables; namespace System.Reactive.Concurrency { public static partial class Scheduler { /// /// Schedules an action to be executed. /// /// Scheduler to execute the action on. /// Action to execute. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. public static IDisposable Schedule(this IScheduler scheduler, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } // Surprisingly, passing the method group of Invoke will create a fresh // delegate each time although it's static, while an anonymous // lambda without the need of a closure will be cached. // Once Roslyn supports caching delegates for method groups, // the anonymous lambda can be replaced by the method group again. Until then, // to avoid the repetition of code, the call to Invoke is left intact. // Watch https://github.com/dotnet/roslyn/issues/5835 return scheduler.Schedule(action, static (s, a) => Invoke(s, a)); } /// /// Schedules an action to be executed. /// /// Scheduler to execute the action on. /// A state object to be passed to . /// Action to execute. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. // Note: The naming of that method differs because otherwise, the signature would cause ambiguities. internal static IDisposable ScheduleAction(this IScheduler scheduler, TState state, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } return scheduler.Schedule( (action, state), (_, tuple) => { tuple.action(tuple.state); return Disposable.Empty; }); } /// /// Schedules an action to be executed. /// /// Scheduler to execute the action on. /// A state object to be passed to . /// Action to execute. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. // Note: The naming of that method differs because otherwise, the signature would cause ambiguities. internal static IDisposable ScheduleAction(this IScheduler scheduler, TState state, Func action) { if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); if (action == null) throw new ArgumentNullException(nameof(action)); return scheduler.Schedule( (action, state), static (_, tuple) => tuple.action(tuple.state)); } /// /// Schedules an action to be executed after the specified relative due time. /// /// Scheduler to execute the action on. /// Action to execute. /// Relative time after which to execute the action. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. public static IDisposable Schedule(this IScheduler scheduler, TimeSpan dueTime, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } // See note above. return scheduler.Schedule(action, dueTime, static (s, a) => Invoke(s, a)); } /// /// Schedules an action to be executed after the specified relative due time. /// /// Scheduler to execute the action on. /// Action to execute. /// A state object to be passed to . /// Relative time after which to execute the action. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. internal static IDisposable ScheduleAction(this IScheduler scheduler, TState state, TimeSpan dueTime, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } // See note above. return scheduler.Schedule((state, action), dueTime, static (s, tuple) => Invoke(s, tuple)); } /// /// Schedules an action to be executed after the specified relative due time. /// /// Scheduler to execute the action on. /// Action to execute. /// A state object to be passed to . /// Relative time after which to execute the action. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. internal static IDisposable ScheduleAction(this IScheduler scheduler, TState state, TimeSpan dueTime, Func action) { if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); if (action == null) throw new ArgumentNullException(nameof(action)); // See note above. return scheduler.Schedule((state, action), dueTime, static (s, tuple) => Invoke(s, tuple)); } /// /// Schedules an action to be executed at the specified absolute due time. /// /// Scheduler to execute the action on. /// Action to execute. /// Absolute time at which to execute the action. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } // See note above. return scheduler.Schedule(action, dueTime, static (s, a) => Invoke(s, a)); } /// /// Schedules an action to be executed after the specified relative due time. /// /// Scheduler to execute the action on. /// Action to execute. /// A state object to be passed to . /// Relative time after which to execute the action. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. internal static IDisposable ScheduleAction(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } // See note above. return scheduler.Schedule((state, action), dueTime, static (s, tuple) => Invoke(s, tuple)); } /// /// Schedules an action to be executed after the specified relative due time. /// /// Scheduler to execute the action on. /// Action to execute. /// A state object to be passed to . /// Relative time after which to execute the action. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. internal static IDisposable ScheduleAction(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Func action) { if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); if (action == null) throw new ArgumentNullException(nameof(action)); // See note above. return scheduler.Schedule((state, action), dueTime, static (s, tuple) => Invoke(s, tuple)); } /// /// Schedules an action to be executed. /// /// Scheduler to execute the action on. /// Action to execute. /// The disposable object used to cancel the scheduled action (best effort). /// or is null. public static IDisposable ScheduleLongRunning(this ISchedulerLongRunning scheduler, Action action) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } return scheduler.ScheduleLongRunning(action, static (a, c) => a(c)); } private static IDisposable Invoke(IScheduler scheduler, Action action) { action(); return Disposable.Empty; } private static IDisposable Invoke(IScheduler scheduler, (TState state, Action action) tuple) { tuple.action(tuple.state); return Disposable.Empty; } private static IDisposable Invoke(IScheduler scheduler, (TState state, Func action) tuple) { return tuple.action(tuple.state); } } }