using System; using System.Collections; using System.Runtime.InteropServices; namespace System.Threading { /// Provides a mechanism for executing a method at specified intervals. This class cannot be inherited. /// 1 // Token: 0x02000627 RID: 1575 [ComVisible(true)] public sealed class Timer : MarshalByRefObject, IDisposable { /// Initializes a new instance of the Timer class, using a 32-bit signed integer to specify the time interval. /// A delegate representing a method to be executed. /// An object containing information to be used by the callback method, or null. /// The amount of time to delay before is invoked, in milliseconds. Specify to prevent the timer from starting. Specify zero (0) to start the timer immediately. /// The time interval between invocations of , in milliseconds. Specify to disable periodic signaling. /// The or parameter is negative and is not equal to . /// The parameter is null. // Token: 0x060039CC RID: 14796 RVA: 0x000C6458 File Offset: 0x000C4658 public Timer(TimerCallback callback, object state, int dueTime, int period) { this.Init(callback, state, (long)dueTime, (long)period); } /// Initializes a new instance of the Timer class, using 64-bit signed integers to measure time intervals. /// A delegate representing a method to be executed. /// An object containing information to be used by the callback method, or null. /// The amount of time to delay before is invoked, in milliseconds. Specify to prevent the timer from starting. Specify zero (0) to start the timer immediately. /// The time interval between invocations of , in milliseconds. Specify to disable periodic signaling. /// The or parameter is negative and is not equal to . /// The or parameter is greater than 4294967294. // Token: 0x060039CD RID: 14797 RVA: 0x000C6470 File Offset: 0x000C4670 public Timer(TimerCallback callback, object state, long dueTime, long period) { this.Init(callback, state, dueTime, period); } /// Initializes a new instance of the Timer class, using values to measure time intervals. /// A delegate representing a method to be executed. /// An object containing information to be used by the callback method, or null. /// The representing the amount of time to delay before the parameter invokes its methods. Specify negative one (-1) milliseconds to prevent the timer from starting. Specify zero (0) to start the timer immediately. /// The time interval between invocations of the methods referenced by . Specify negative one (-1) milliseconds to disable periodic signaling. /// The number of milliseconds in the value of or is negative and not equal to , or is greater than . /// The parameter is null. // Token: 0x060039CE RID: 14798 RVA: 0x000C6484 File Offset: 0x000C4684 public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period) { this.Init(callback, state, (long)dueTime.TotalMilliseconds, (long)period.TotalMilliseconds); } /// Initializes a new instance of the Timer class, using 32-bit unsigned integers to measure time intervals. /// A delegate representing a method to be executed. /// An object containing information to be used by the callback method, or null. /// The amount of time to delay before is invoked, in milliseconds. Specify to prevent the timer from starting. Specify zero (0) to start the timer immediately. /// The time interval between invocations of , in milliseconds. Specify to disable periodic signaling. /// The or parameter is negative and is not equal to . /// The parameter is null. // Token: 0x060039CF RID: 14799 RVA: 0x000C64B0 File Offset: 0x000C46B0 [CLSCompliant(false)] public Timer(TimerCallback callback, object state, uint dueTime, uint period) { long num = (long)((dueTime != uint.MaxValue) ? ((ulong)dueTime) : ulong.MaxValue); long num2 = (long)((period != uint.MaxValue) ? ((ulong)period) : ulong.MaxValue); this.Init(callback, state, num, num2); } /// Initializes a new instance of the class with an infinite period and an infinite due time, using the newly created object as the state object. /// A delegate representing a method to be executed. // Token: 0x060039D0 RID: 14800 RVA: 0x000C64F4 File Offset: 0x000C46F4 public Timer(TimerCallback callback) { this.Init(callback, this, -1L, -1L); } // Token: 0x060039D2 RID: 14802 RVA: 0x000C6514 File Offset: 0x000C4714 private void Init(TimerCallback callback, object state, long dueTime, long period) { if (callback == null) { throw new ArgumentNullException("callback"); } this.callback = callback; this.state = state; this.Change(dueTime, period, true); } /// Changes the start time and the interval between method invocations for a timer, using 32-bit signed integers to measure time intervals. /// true if the timer was successfully updated; otherwise, false. /// The amount of time to delay before the invoking the callback method specified when the was constructed, in milliseconds. Specify to prevent the timer from restarting. Specify zero (0) to restart the timer immediately. /// The time interval between invocations of the callback method specified when the was constructed, in milliseconds. Specify to disable periodic signaling. /// The has already been disposed. /// The or parameter is negative and is not equal to . /// 2 // Token: 0x060039D3 RID: 14803 RVA: 0x000C654C File Offset: 0x000C474C public bool Change(int dueTime, int period) { return this.Change((long)dueTime, (long)period, false); } /// Changes the start time and the interval between method invocations for a timer, using values to measure time intervals. /// true if the timer was successfully updated; otherwise, false. /// A representing the amount of time to delay before invoking the callback method specified when the was constructed. Specify negative one (-1) milliseconds to prevent the timer from restarting. Specify zero (0) to restart the timer immediately. /// The time interval between invocations of the callback method specified when the was constructed. Specify negative one (-1) milliseconds to disable periodic signaling. /// The has already been disposed. /// The or parameter, in milliseconds, is less than -1. /// The or parameter, in milliseconds, is greater than 4294967294. /// 2 // Token: 0x060039D4 RID: 14804 RVA: 0x000C655C File Offset: 0x000C475C public bool Change(TimeSpan dueTime, TimeSpan period) { return this.Change((long)dueTime.TotalMilliseconds, (long)period.TotalMilliseconds, false); } /// Changes the start time and the interval between method invocations for a timer, using 32-bit unsigned integers to measure time intervals. /// true if the timer was successfully updated; otherwise, false. /// The amount of time to delay before the invoking the callback method specified when the was constructed, in milliseconds. Specify to prevent the timer from restarting. Specify zero (0) to restart the timer immediately. /// The time interval between invocations of the callback method specified when the was constructed, in milliseconds. Specify to disable periodic signaling. /// The has already been disposed. /// 2 // Token: 0x060039D5 RID: 14805 RVA: 0x000C6580 File Offset: 0x000C4780 [CLSCompliant(false)] public bool Change(uint dueTime, uint period) { long num = (long)((dueTime != uint.MaxValue) ? ((ulong)dueTime) : ulong.MaxValue); long num2 = (long)((period != uint.MaxValue) ? ((ulong)period) : ulong.MaxValue); return this.Change(num, num2, false); } /// Releases all resources used by the current instance of . /// 2 // Token: 0x060039D6 RID: 14806 RVA: 0x000C65B8 File Offset: 0x000C47B8 public void Dispose() { if (this.disposed) { return; } this.disposed = true; Timer.scheduler.Remove(this); } /// Changes the start time and the interval between method invocations for a timer, using 64-bit signed integers to measure time intervals. /// true if the timer was successfully updated; otherwise, false. /// The amount of time to delay before the invoking the callback method specified when the was constructed, in milliseconds. Specify to prevent the timer from restarting. Specify zero (0) to restart the timer immediately. /// The time interval between invocations of the callback method specified when the was constructed, in milliseconds. Specify to disable periodic signaling. /// The has already been disposed. /// The or parameter is less than -1. /// The or parameter is greater than 4294967294. /// 2 // Token: 0x060039D7 RID: 14807 RVA: 0x000C65D8 File Offset: 0x000C47D8 public bool Change(long dueTime, long period) { return this.Change(dueTime, period, false); } // Token: 0x060039D8 RID: 14808 RVA: 0x000C65E4 File Offset: 0x000C47E4 private bool Change(long dueTime, long period, bool first) { if (dueTime > (long)((ulong)(-2))) { throw new ArgumentOutOfRangeException("Due time too large"); } if (period > (long)((ulong)(-2))) { throw new ArgumentOutOfRangeException("Period too large"); } if (dueTime < -1L) { throw new ArgumentOutOfRangeException("dueTime"); } if (period < -1L) { throw new ArgumentOutOfRangeException("period"); } if (this.disposed) { return false; } this.due_time_ms = dueTime; this.period_ms = period; long num; if (dueTime == 0L) { num = 0L; } else if (dueTime < 0L) { num = long.MaxValue; if (first) { this.next_run = num; return true; } } else { num = dueTime * 10000L + DateTime.GetTimeMonotonic(); } Timer.scheduler.Change(this, num); return true; } /// Releases all resources used by the current instance of and signals when the timer has been disposed of. /// true if the function succeeds; otherwise, false. /// The to be signaled when the Timer has been disposed of. /// The parameter is null. /// 2 // Token: 0x060039D9 RID: 14809 RVA: 0x000C66AC File Offset: 0x000C48AC public bool Dispose(WaitHandle notifyObject) { if (notifyObject == null) { throw new ArgumentNullException("notifyObject"); } this.Dispose(); NativeEventCalls.SetEvent_internal(notifyObject.Handle); return true; } // Token: 0x04001754 RID: 5972 private const long MaxValue = 4294967294L; // Token: 0x04001755 RID: 5973 private static Timer.Scheduler scheduler = Timer.Scheduler.Instance; // Token: 0x04001756 RID: 5974 private TimerCallback callback; // Token: 0x04001757 RID: 5975 private object state; // Token: 0x04001758 RID: 5976 private long due_time_ms; // Token: 0x04001759 RID: 5977 private long period_ms; // Token: 0x0400175A RID: 5978 private long next_run; // Token: 0x0400175B RID: 5979 private bool disposed; // Token: 0x02000628 RID: 1576 private sealed class TimerComparer : IComparer { // Token: 0x060039DB RID: 14811 RVA: 0x000C66E8 File Offset: 0x000C48E8 public int Compare(object x, object y) { Timer timer = x as Timer; if (timer == null) { return -1; } Timer timer2 = y as Timer; if (timer2 == null) { return 1; } long num = timer.next_run - timer2.next_run; if (num == 0L) { return 0; } return (num <= 0L) ? (-1) : 1; } } // Token: 0x02000629 RID: 1577 private sealed class Scheduler { // Token: 0x060039DC RID: 14812 RVA: 0x000C6738 File Offset: 0x000C4938 private Scheduler() { this.list = new SortedList(new Timer.TimerComparer(), 1024); new Thread(new ThreadStart(this.SchedulerThread)) { IsBackground = true }.Start(); } // Token: 0x17000B1C RID: 2844 // (get) Token: 0x060039DE RID: 14814 RVA: 0x000C678C File Offset: 0x000C498C public static Timer.Scheduler Instance { get { return Timer.Scheduler.instance; } } // Token: 0x060039DF RID: 14815 RVA: 0x000C6794 File Offset: 0x000C4994 public void Remove(Timer timer) { if (timer.next_run == 0L || timer.next_run == 9223372036854775807L) { return; } lock (this) { this.InternalRemove(timer); } } // Token: 0x060039E0 RID: 14816 RVA: 0x000C67FC File Offset: 0x000C49FC public void Change(Timer timer, long new_next_run) { lock (this) { this.InternalRemove(timer); if (new_next_run == 9223372036854775807L) { timer.next_run = new_next_run; } else if (!timer.disposed) { timer.next_run = new_next_run; this.Add(timer); if (this.list.GetByIndex(0) == timer) { Monitor.Pulse(this); } } } } // Token: 0x060039E1 RID: 14817 RVA: 0x000C6890 File Offset: 0x000C4A90 private void Add(Timer timer) { int num = this.list.IndexOfKey(timer); if (num != -1) { bool flag = long.MaxValue - timer.next_run > 20000L; Timer timer2; do { num++; if (flag) { timer.next_run += 1L; } else { timer.next_run -= 1L; } if (num >= this.list.Count) { break; } timer2 = (Timer)this.list.GetByIndex(num); } while (timer2.next_run == timer.next_run); } this.list.Add(timer, timer); } // Token: 0x060039E2 RID: 14818 RVA: 0x000C6954 File Offset: 0x000C4B54 private int InternalRemove(Timer timer) { int num = this.list.IndexOfKey(timer); if (num >= 0) { this.list.RemoveAt(num); } return num; } // Token: 0x060039E3 RID: 14819 RVA: 0x000C6984 File Offset: 0x000C4B84 private void SchedulerThread() { Thread.CurrentThread.Name = "Timer-Scheduler"; ArrayList arrayList = new ArrayList(512); for (;;) { long timeMonotonic = DateTime.GetTimeMonotonic(); lock (this) { int num = this.list.Count; for (int i = 0; i < num; i++) { Timer timer = (Timer)this.list.GetByIndex(i); if (timer.next_run > timeMonotonic) { break; } this.list.RemoveAt(i); num--; i--; ThreadPool.QueueUserWorkItem(new WaitCallback(timer.callback.Invoke), timer.state); long period_ms = timer.period_ms; long due_time_ms = timer.due_time_ms; bool flag = period_ms == -1L || ((period_ms == 0L || period_ms == -1L) && due_time_ms != -1L); if (flag) { timer.next_run = long.MaxValue; } else { timer.next_run = DateTime.GetTimeMonotonic() + 10000L * timer.period_ms; arrayList.Add(timer); } } num = arrayList.Count; for (int i = 0; i < num; i++) { Timer timer2 = (Timer)arrayList[i]; this.Add(timer2); } arrayList.Clear(); this.ShrinkIfNeeded(arrayList, 512); int capacity = this.list.Capacity; num = this.list.Count; if (capacity > 1024 && num > 0 && capacity / num > 3) { this.list.Capacity = num * 2; } long num2 = long.MaxValue; if (this.list.Count > 0) { num2 = ((Timer)this.list.GetByIndex(0)).next_run; } int num3 = -1; if (num2 != 9223372036854775807L) { long num4 = num2 - DateTime.GetTimeMonotonic(); num3 = (int)(num4 / 10000L); if (num3 < 0) { num3 = 0; } } Monitor.Wait(this, num3); } } } // Token: 0x060039E4 RID: 14820 RVA: 0x000C6BD8 File Offset: 0x000C4DD8 private void ShrinkIfNeeded(ArrayList list, int initial) { int capacity = list.Capacity; int count = list.Count; if (capacity > initial && count > 0 && capacity / count > 3) { list.Capacity = count * 2; } } // Token: 0x0400175C RID: 5980 private static Timer.Scheduler instance = new Timer.Scheduler(); // Token: 0x0400175D RID: 5981 private SortedList list; } } }