public SlowlyScheduledWorkItem(TaskPoolScheduler scheduler, TState state, TimeSpan dueTime, Func <IScheduler, TState, IDisposable> action) { _state = state; _action = action; _scheduler = scheduler; var ct = new CancellationDisposable(); Disposable.SetSingle(ref _cancel, ct); TaskHelpers.Delay(dueTime, ct.Token).ContinueWith( (_, thisObject) => { var @this = (SlowlyScheduledWorkItem <TState>)thisObject; if (!Disposable.GetIsDisposed(ref @this._cancel)) { Disposable.TrySetMultiple(ref @this._cancel, @this._action(@this._scheduler, @this._state)); } }, this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, scheduler._taskFactory.Scheduler); }
public SlowlyScheduledWorkItem(TaskPoolScheduler scheduler, TState state, TimeSpan dueTime, Func <IScheduler, TState, IDisposable> action) { _state = state; _action = action; _scheduler = scheduler; var ct = new CancellationDisposable(); _cancel.Disposable = ct; TaskHelpers.Delay(dueTime, ct.Token).ContinueWith( (_, thisObject) => { var @this = (SlowlyScheduledWorkItem <TState>)thisObject !; if (!@this._cancel.IsDisposed) { @this._cancel.Disposable = @this._action(@this._scheduler, @this._state); } }, this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, scheduler._taskFactory.Scheduler ?? TaskScheduler.Default); }
public ScheduledWorkItem(TaskPoolScheduler scheduler, TState state, Func <IScheduler, TState, IDisposable> action) { _state = state; _action = action; _scheduler = scheduler; var cancelable = new CancellationDisposable(); Disposable.SetSingle(ref _cancel, cancelable); scheduler._taskFactory.StartNew( thisObject => { var @this = (ScheduledWorkItem <TState>)thisObject; // // BREAKING CHANGE v2.0 > v1.x - No longer escalating exceptions using a throwing // helper thread. // // Our manual escalation based on the creation of a throwing thread was merely to // expedite the process of throwing the exception that would otherwise occur on the // finalizer thread at a later point during the app's lifetime. // // However, it also prevented applications from observing the exception through // the TaskScheduler.UnobservedTaskException static event. Also, starting form .NET // 4.5, the default behavior of the task pool is not to take down the application // when an exception goes unobserved (done as part of the async/await work). It'd // be weird for Rx not to follow the platform defaults. // // General implementation guidelines for schedulers (in order of importance): // // 1. Always thunk through to the underlying infrastructure with a wrapper that's as tiny as possible. // 2. Global exception notification/handling mechanisms shouldn't be bypassed. // 3. Escalation behavior for exceptions is left to the underlying infrastructure. // // The Catch extension method for IScheduler (added earlier) allows to re-route // exceptions at stage 2. If the exception isn't handled at the Rx level, it // propagates by means of a rethrow, falling back to behavior in 3. // Disposable.TrySetSerial(ref @this._cancel, @this._action(@this._scheduler, @this._state)); }, this, cancelable.Token); }
public LongScheduledWorkItem(TaskPoolScheduler scheduler, TState state, Action <TState, ICancelable> action) { _state = state; _action = action; scheduler._taskFactory.StartNew( thisObject => { var @this = (LongScheduledWorkItem <TState>)thisObject; // // Notice we don't check _cancel.IsDisposed. The contract for ISchedulerLongRunning // requires us to ensure the scheduled work gets an opportunity to observe // the cancellation request. // @this._action(@this._state, @this); }, this, TaskCreationOptions.LongRunning); }