private void OnFileFinishedChangingEvent(object sender, FileFinishedChangingEventArgs e) { if (e.ChangeType == FileEventType.Deleted || e.ChangeType == FileEventType.Renamed) return; var fileFinishedChangingMessage = new FileFinishedChangingMessage { CorrelationId = CombGuid.Generate(), FilePath = e.FilePath, Folder = (FolderElement)e.UserState }; BusDriver.Instance.GetBus(CommanderService.CommandManagerBusName).Publish(fileFinishedChangingMessage); }
static void OnFileFinishedChangingEvent(object sender, FileFinishedChangingEventArgs e) { lock (Lock) { Console.WriteLine("OnFileFinishedChangingEvent:"); Console.WriteLine(" FilePath = {0}", e.FilePath); Console.WriteLine(" ChangeType = {0}", Enum.GetName(typeof (FileEventType), e.ChangeType)); Console.WriteLine(); } }
private void OnFileDeleted(object sender, FileSystemEventArgs e) { var filePath = e.FullPath; //There is no good way of detecting files without extensions and directories with full stops in name. The file/directory has been deleted so we can't find it out from the path. var isDirectory = Path.GetExtension(filePath) == string.Empty; if (isDirectory) { lock (_filesRaisingEventsLock) { var filesInDirectory = _filesChanging.Keys.Where(x => x.StartsWith(e.FullPath + "/")); foreach (var fileInDirectory in filesInDirectory) { Pop(fileInDirectory); } } var directoryDeletedEventArgs = new DirectoryDeletedEventArgs(e.FullPath, UserState); RaiseAsynchronousOnDirectoryDeletedEvent(directoryDeletedEventArgs); return; } if (!ShouldMonitorFile(filePath)) return; lock (_filesRaisingEventsLock) { if (_filesChanging.ContainsKey(filePath)) { Pop(filePath); var fileFinishedChangingEventArgs = new FileFinishedChangingEventArgs(filePath, FileEventType.Deleted, UserState); RaiseAsynchronousOnFileFinishedChangingEvent(fileFinishedChangingEventArgs); } } var fileDeletedEventArgs = new FileDeletedEventArgs(e.FullPath, UserState); RaiseAsynchronousOnFileDeletedEvent(fileDeletedEventArgs); }
/// <summary> /// Will raise the event on the calling thread synchronously. /// i.e. it will wait until all event handlers have processed the event. /// </summary> /// <param name="state">The state to be passed to the event.</param> private void RaiseCrossThreadOnFileFinishedChangingEvent(FileFinishedChangingEventArgs e) { _asyncOperation.SynchronizationContext.Send(new SendOrPostCallback(AsynchronousOnFileFinishedChangingEventRaised), e); }
/// <summary> /// Will raise the event on the current thread synchronously. /// i.e. it will wait until all event handlers have processed the event. /// </summary> /// <param name="e">The state to be passed to the event.</param> private void RaiseOnFileFinishedChangingEvent(FileFinishedChangingEventArgs e) { // Make a temporary copy of the event to avoid possibility of // a race condition if the last subscriber unsubscribes // immediately after the null check and before the event is raised. FileFinishedChangingEventHandler eventHandler; if (!Monitor.TryEnter(_fileFinishedChangingEventLock, _lockTimeout)) { throw new ApplicationException("Timeout waiting for lock - RaiseOnFileFinishedChangingEvent"); } try { eventHandler = _fileFinishedChangingEvent; } finally { Monitor.Exit(_fileFinishedChangingEventLock); } OnFileFinishedChangingEvent(e); if (eventHandler != null) { eventHandler(this, e); } }
/// <summary> /// Will raise the event on the calling thread asynchronously. /// i.e. it will immediatly continue processing even though event /// handlers have not processed the event yet. /// </summary> /// <param name="state">The state to be passed to the event.</param> private void RaiseAsynchronousOnFileFinishedChangingEvent(FileFinishedChangingEventArgs e) { _asyncOperation.Post(new SendOrPostCallback(AsynchronousOnFileFinishedChangingEventRaised), e); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <remarks>We using an in memory queue and poping them off one by one. We may have 1000s of file events so executing them all /// at once does not scale well.</remarks> private void OnTimeUp(object sender, ElapsedEventArgs e) { lock (_filesRaisingEventsLock) { if (_timer == null) return; _timer.Stop(); if (!string.IsNullOrEmpty(_nextFileToCheck) && _filesChanging.ContainsKey(_nextFileToCheck)) { var item = _filesChanging[_nextFileToCheck]; if (item.FireTime <= DateTime.Now) { var fileFinishedChangingEventArgs = new FileFinishedChangingEventArgs(item.FilePath, item.FileEventType, UserState); _fileFinishedChangingCallback(fileFinishedChangingEventArgs); } } GetNextFileToCheck(); } }
private void OnFileRenamed(object sender, RenamedEventArgs e) { var filePath = e.FullPath; var isDirectory = Directory.Exists(filePath) && (File.GetAttributes(filePath) & FileAttributes.Directory) == FileAttributes.Directory; if (isDirectory) { lock (_filesRaisingEventsLock) { var filesInDirectory = _filesChanging.Keys.Where(x => x.StartsWith(e.OldFullPath + "/")); foreach (var fileInDirectory in filesInDirectory) { var fileInDirectoryPath = _filesChanging[fileInDirectory].FilePath; Pop(fileInDirectory); var fileFinishedChangingEventArgs = new FileFinishedChangingEventArgs(fileInDirectoryPath, FileEventType.Renamed, UserState); RaiseAsynchronousOnFileFinishedChangingEvent(fileFinishedChangingEventArgs); } } var directoryRenamedEventArgs = new DirectoryRenamedEventArgs(e.OldFullPath, e.FullPath, UserState); RaiseAsynchronousOnDirectoryRenamedEvent(directoryRenamedEventArgs); return; } if (!ShouldMonitorFile(filePath)) return; lock (_filesRaisingEventsLock) { if (_filesChanging.ContainsKey(filePath)) { Pop(filePath); var fileFinishedChangingEventArgs = new FileFinishedChangingEventArgs(filePath, FileEventType.Renamed, UserState); RaiseAsynchronousOnFileFinishedChangingEvent(fileFinishedChangingEventArgs); } } var fileRenamedEventArgs = new FileRenamedEventArgs(e.OldFullPath, e.FullPath, UserState); RaiseAsynchronousOnFileRenamedEvent(fileRenamedEventArgs); }
/// <summary> /// Template method to add default behaviour for the event /// </summary> private void OnFileFinishedChangingEvent(FileFinishedChangingEventArgs e) { // TODO: Implement default behaviour of OnFileFinishedChangingEvent }
private void OnFileFinishedChanging(FileFinishedChangingEventArgs e) { lock (_filesRaisingEventsLock) { var filePath = e.FilePath; if (_filesChanging.ContainsKey(filePath)) { if ( IsFileLocked(filePath)) { //The file is still currently in use, lets try raise the event later Touch(filePath); } else { Pop(filePath); var fileFinishedChangingEventArgs = new FileFinishedChangingEventArgs(e.FilePath, e.ChangeType, UserState); //We only want to know about the last event, not any that may have happened in the mean time _filesFinishedChanging[fileFinishedChangingEventArgs.FilePath] = fileFinishedChangingEventArgs; RaiseAsynchronousOnFileFinishedChangingEvent(fileFinishedChangingEventArgs); if (_filesChanging == null || _filesChanging.Count < 1) { if (_filesFinishedChanging != null && _filesFinishedChanging.Count > 0) { //There are no more files that are in the change queue so let everyone know the files have finished changing var filesFinishedChangingEventArgs = new FilesFinishedChangingEventArgs(new List<FileFinishedChangingEventArgs>(_filesFinishedChanging.Values), UserState); RaiseAsynchronousOnFilesFinishedChangingEvent(filesFinishedChangingEventArgs); _filesFinishedChanging = new Dictionary<string, FileFinishedChangingEventArgs>(); } } } } } }