123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #if !UNITY_METRO
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text;
- using UniRx.InternalUtil;
- namespace UniRx
- {
- public static partial class Scheduler
- {
- public static readonly IScheduler ThreadPool = new ThreadPoolScheduler();
- class ThreadPoolScheduler : IScheduler, ISchedulerPeriodic
- {
- public ThreadPoolScheduler()
- {
- }
- public DateTimeOffset Now
- {
- get { return Scheduler.Now; }
- }
- public IDisposable Schedule(Action action)
- {
- var d = new BooleanDisposable();
- System.Threading.ThreadPool.QueueUserWorkItem(_ =>
- {
- if (!d.IsDisposed)
- {
- action();
- }
- });
- return d;
- }
- public IDisposable Schedule(DateTimeOffset dueTime, Action action)
- {
- return Schedule(dueTime - Now, action);
- }
- public IDisposable Schedule(TimeSpan dueTime, Action action)
- {
- return new Timer(dueTime, action);
- }
- public IDisposable SchedulePeriodic(TimeSpan period, Action action)
- {
- return new PeriodicTimer(period, action);
- }
- public void ScheduleQueueing<T>(ICancelable cancel, T state, Action<T> action)
- {
- System.Threading.ThreadPool.QueueUserWorkItem(callBackState =>
- {
- if (!cancel.IsDisposed)
- {
- action((T)callBackState);
- }
- }, state);
- }
- // timer was borrwed from Rx Official
- sealed class Timer : IDisposable
- {
- static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
- private readonly SingleAssignmentDisposable _disposable;
- private Action _action;
- private System.Threading.Timer _timer;
- private bool _hasAdded;
- private bool _hasRemoved;
- public Timer(TimeSpan dueTime, Action action)
- {
- _disposable = new SingleAssignmentDisposable();
- _disposable.Disposable = Disposable.Create(Unroot);
- _action = action;
- _timer = new System.Threading.Timer(Tick, null, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
- lock (s_timers)
- {
- if (!_hasRemoved)
- {
- s_timers.Add(_timer);
- _hasAdded = true;
- }
- }
- }
- private void Tick(object state)
- {
- try
- {
- if (!_disposable.IsDisposed)
- {
- _action();
- }
- }
- finally
- {
- Unroot();
- }
- }
- private void Unroot()
- {
- _action = Stubs.Nop;
- var timer = default(System.Threading.Timer);
- lock (s_timers)
- {
- if (!_hasRemoved)
- {
- timer = _timer;
- _timer = null;
- if (_hasAdded && timer != null)
- s_timers.Remove(timer);
- _hasRemoved = true;
- }
- }
- if (timer != null)
- timer.Dispose();
- }
- public void Dispose()
- {
- _disposable.Dispose();
- }
- }
- sealed class PeriodicTimer : IDisposable
- {
- static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
- private Action _action;
- private System.Threading.Timer _timer;
- private readonly AsyncLock _gate;
- public PeriodicTimer(TimeSpan period, Action action)
- {
- this._action = action;
- this._timer = new System.Threading.Timer(Tick, null, period, period);
- this._gate = new AsyncLock();
- lock (s_timers)
- {
- s_timers.Add(_timer);
- }
- }
- private void Tick(object state)
- {
- _gate.Wait(() =>
- {
- _action();
- });
- }
- public void Dispose()
- {
- var timer = default(System.Threading.Timer);
- lock (s_timers)
- {
- timer = _timer;
- _timer = null;
- if (timer != null)
- s_timers.Remove(timer);
- }
- if (timer != null)
- {
- timer.Dispose();
- _action = Stubs.Nop;
- }
- }
- }
- }
- }
- }
- #endif
|