public void OnFileChanged(TrackedFileEventArgs file) { if (CancellationToken.IsCancellationRequested) { return; } var filePath = file.Path; ICancellableTask task = null; // Check if we have an outstanding line count task. If we don't, kick one off lock (OutstandingLineCounts) { if (!OutstandingLineCounts.ContainsKey(filePath)) { // kick off and add line count task task = CancellableTaskRunner.Run(async token => { await CalculateLineCount(filePath, token); }, onThreadPoolThread: true); OutstandingLineCounts.Add(filePath, task); } } task?.Task.ContinueWith(t => { if (t.IsFaulted) { OnLineCountFailed?.Invoke(new LineCountFailedEventArgs(filePath, t.Exception)); } }); }
public void OnFileRemoved(TrackedFileEventArgs file) { var filePath = file.Path; // Cancel an outstanding line count task for this file, if one exists lock (OutstandingLineCounts) { if (OutstandingLineCounts.TryGetValue(filePath, out var task)) { task.Cancel(); } } lock (PathLineCounts) { // NOTE: if the key doesn't exist, the method will return null, // not throw an exception, per method documentation PathLineCounts.Remove(filePath); } }
protected async Task CalculateLineCount(string filePath, CancellationToken taskCancellationToken) { if (IsCancellationRequested()) { return; } try { var lineCount = await LineCounter.CountLinesAsync(filePath, taskCancellationToken); if (IsCancellationRequested()) { return; } var result = AddOrUpdateLineCount(filePath, lineCount); if (result.previous == null) { OnLineCountCreated?.Invoke(new LineCountCreatedEventArgs(filePath, result.current)); } else { OnLineCountUpdated?.Invoke(new LineCountUpdatedEventArgs(filePath, result.current, result.previous)); } } finally { lock (OutstandingLineCounts) { OutstandingLineCounts.Remove(filePath); } } bool IsCancellationRequested() => CancellationToken.IsCancellationRequested || taskCancellationToken.IsCancellationRequested; }