protected void RaiseEvents(Queue deQueue) { if ((deQueue != null) && (deQueue.Count > 0)) { DelayedEvent de = null; while (deQueue.Count > 0) { de = deQueue.Dequeue() as DelayedEvent; switch (de.Args.ChangeType) { case WatcherChangeTypes.Changed: this.OnChanged(de.Args); break; case WatcherChangeTypes.Created: this.OnCreated(de.Args); break; case WatcherChangeTypes.Deleted: this.OnDeleted(de.Args); break; case WatcherChangeTypes.Renamed: this.OnRenamed(de.Args as RenamedEventArgs); break; } } } }
public virtual bool IsDuplicate(object obj) { DelayedEvent delayedEvent = obj as DelayedEvent; if (delayedEvent == null) { return(false); // this is not null so they are different } else { FileSystemEventArgs eO1 = this._args; RenamedEventArgs reO1 = this._args as RenamedEventArgs; FileSystemEventArgs eO2 = delayedEvent._args; RenamedEventArgs reO2 = delayedEvent._args as RenamedEventArgs; // The events are equal only if they are of the same type (reO1 and reO2 // are both null or NOT NULL) and have all properties equal. // We also eliminate Changed events that follow recent Created events // because many apps create new files by creating an empty file and then // they update the file with the file content. return(((eO1 != null && eO2 != null && eO1.ChangeType == eO2.ChangeType && eO1.FullPath == eO2.FullPath && eO1.Name == eO2.Name) && ((reO1 == null & reO2 == null) || (reO1 != null && reO2 != null && reO1.OldFullPath == reO2.OldFullPath && reO1.OldName == reO2.OldName))) || (eO1 != null && eO2 != null && eO1.ChangeType == WatcherChangeTypes.Created && eO2.ChangeType == WatcherChangeTypes.Changed && eO1.FullPath == eO2.FullPath && eO1.Name == eO2.Name)); } }
private void ElapsedEventHandler(Object sender, ElapsedEventArgs e) { // We don't fire the events inside the lock. We will queue them here until // the code exits the locks. Queue eventsToBeFired = null; if (Monitor.TryEnter(this._enterThread)) { // Only one thread at a time is processing the events try { eventsToBeFired = new Queue(32); // Lock the collection while processing the events lock (this._events.SyncRoot) { DelayedEvent current = null; for (int i = 0; i < this._events.Count; i++) { current = this._events[i] as DelayedEvent; if (current.Delayed) { // This event has been delayed already so we can fire it // We just need to remove any duplicates for (int j = i + 1; j < this._events.Count; j++) { if (current.IsDuplicate(this._events[j])) { // Removing later duplicates this._events.RemoveAt(j); j--; // Don't skip next event } } // Add the event to the list of events to be fired eventsToBeFired.Enqueue(current); // Remove it from the current list this._events.RemoveAt(i); i--; // Don't skip next event } else { // This event was not delayed yet, so we will delay processing // this event for at least one timer interval current.Delayed = true; } } } } finally { Monitor.Exit(this._enterThread); } } // else - this timer event was skipped, processing will happen during the next timer event // Now fire all the events if any events are in eventsToBeFired this.RaiseEvents(eventsToBeFired); }