public override void Run(object sender, DoWorkEventArgs ev) { try { while (true) { bool satisfaction = false; string vsn = ""; watcher.EventArrived += new EventArrivedEventHandler( (send, eve) => { if (((ManagementBaseObject)eve.NewEvent["TargetInstance"])["Description"].ToString() == "Removable Disk") { satisfaction = true; vsn = ((ManagementBaseObject)eve.NewEvent["TargetInstance"])["VolumeSerialNumber"].ToString(); } }); watcher.Start(); WaitHandle wh = new ManualResetEvent(false); while (!satisfaction) { if ((sender as BackgroundWorker).CancellationPending == true) { ev.Cancel = true; Dispose(); return; } wh.WaitOne(5000); } ; watcher.Stop(); var eventsWithCallbacks = EventToCallbackMapping.Where(x => (x.Key as USBInsertionEvent).VolumeSerialNumber.Equals(vsn)); // Execute callbacks foreach (var eventWithCallback in eventsWithCallbacks) { foreach (var callback in eventWithCallback.Value) { callback.Invoke(); } } } } catch (Exception ex) { watcher.Dispose(); throw ex; } }
public override void Run(object sender, DoWorkEventArgs ev) { // Sort the items based off the next interval from now var now = DateTime.Now; foreach (var evn in EventToCallbackMapping.Keys) { var dte = evn as DateTimeEvent; var item = EventToCallbackMapping.SingleOrDefault(x => x.Key.Id == dte.Id); EventToCallbackMapping.Remove(item.Key); // Run events that are past-due if (dte.RunIfMissed) { foreach (var cb in item.Value) { cb.Invoke(); } } (item.Key as DateTimeEvent).Next = now.AddMinutes(dte.IntervalMinutes); EventToCallbackMapping.Add(item.Key, item.Value); } ///////////////////////////////////////////////////////// while (true) { if (EventToCallbackMapping.Count > 0) { var eventWithCallbacks = EventToCallbackMapping.First(); EventToCallbackMapping.Remove(eventWithCallbacks.Key); // Effectively pop front var dte = (eventWithCallbacks.Key as DateTimeEvent); // Grab the events as date time events because that's what they are! var waitTime = 0.0; var next = dte.Next; // Determine how long to wait to invoke callback if (next > DateTime.Now) { var timeSince = (DateTime.Now - next).TotalMinutes; var x = Math.Floor(timeSince / dte.IntervalMinutes); next = next.AddMinutes(dte.IntervalMinutes * (x + 1)); waitTime = Math.Max(0, (next - DateTime.Now).TotalMilliseconds); } var sleepInterval = 5000; WaitHandle wh = new ManualResetEvent(false); for (int i = sleepInterval; i <= waitTime; i += sleepInterval) { if ((sender as BackgroundWorker).CancellationPending == true) { ev.Cancel = true; if (dte.RunIfMissed) { EventToCallbackMapping.Add(eventWithCallbacks.Key, eventWithCallbacks.Value); } return; } wh.WaitOne(sleepInterval); } foreach (var callback in eventWithCallbacks.Value) { callback.Invoke(); } if (dte.IntervalMinutes == -1) // End of month logic { dte.Next = dte.Next.AddMonths(1); } else { dte.Next = dte.Next.AddMinutes(dte.IntervalMinutes); } // Re-insert the event into it's proper position (its a SortedDictionary) EventToCallbackMapping.Add(eventWithCallbacks.Key, eventWithCallbacks.Value); } Thread.Sleep(5000); } }