ControlScheduler
Represents an object that schedules units of work on the message loop associated with a Windows Forms control.
using System.Reactive.Disposables;
using System.Threading;
using System.Windows.Forms;
namespace System.Reactive.Concurrency
{
public class ControlScheduler : LocalScheduler, ISchedulerPeriodic
{
private readonly Control _control;
public Control Control => _control;
public ControlScheduler(Control control)
{
if (control == null)
throw new ArgumentNullException("control");
_control = control;
}
public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
{
if (action == null)
throw new ArgumentNullException("action");
if (_control.get_IsDisposed())
return Disposable.Empty;
SingleAssignmentDisposable d = new SingleAssignmentDisposable();
_control.BeginInvoke((Delegate)(Action)delegate {
if (!_control.get_IsDisposed() && !d.IsDisposed)
d.Disposable = action(this, state);
});
return d;
}
public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
{
if (action == null)
throw new ArgumentNullException("action");
TimeSpan dt = Scheduler.Normalize(dueTime);
if (dt.Ticks == 0)
return Schedule(state, action);
Func<IScheduler, TState, IDisposable> func = delegate(IScheduler scheduler1, TState state1) {
MultipleAssignmentDisposable d = new MultipleAssignmentDisposable();
Timer timer = new Timer();
timer.add_Tick((EventHandler)delegate {
Timer val2 = Interlocked.Exchange<Timer>(ref timer, null);
if (val2 != null)
try {
if (!_control.get_IsDisposed() && !d.IsDisposed)
d.Disposable = action(scheduler1, state1);
} finally {
val2.Stop();
action = null;
}
});
timer.set_Interval((int)dt.TotalMilliseconds);
timer.Start();
d.Disposable = Disposable.Create(delegate {
Timer val = Interlocked.Exchange<Timer>(ref timer, null);
if (val != null) {
val.Stop();
action = ((IScheduler _, TState __) => Disposable.Empty);
}
});
return d;
};
if (_control.get_InvokeRequired())
return Schedule(state, func);
return func(this, state);
}
public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
{
if (period.TotalMilliseconds < 1)
throw new ArgumentOutOfRangeException("period");
if (action == null)
throw new ArgumentNullException("action");
Func<IScheduler, TState, IDisposable> func = delegate(IScheduler scheduler1, TState state1) {
Timer timer = new Timer();
timer.add_Tick((EventHandler)delegate {
if (!_control.get_IsDisposed())
state1 = action(state1);
});
timer.set_Interval((int)period.TotalMilliseconds);
timer.Start();
return Disposable.Create(delegate {
Timer val = Interlocked.Exchange<Timer>(ref timer, null);
if (val != null) {
val.Stop();
action = ((TState _) => _);
}
});
};
if (_control.get_InvokeRequired())
return Schedule(state, func);
return func(this, state);
}
}
}