private Task ProcessFiles() { return(Task.Run(async() => { var fileInfos = new DirectoryInfo(FilePath).GetFiles(FilePattern); foreach (var fileInfo in fileInfos) { var newNumLines = await GetLineCount(fileInfo.FullName); var oldFileInfoPair = FileLineMap.FirstOrDefault(fi => fi.Key.Name == fileInfo.Name); if (!oldFileInfoPair.Equals(default(KeyValuePair <FileInfo, int>)) && oldFileInfoPair.Key.LastWriteTime != fileInfo.LastWriteTime) { // update the # of lines (other FileInfo properties will be refreshed in RemoveDeletedFiles) if (FileLineMap.TryUpdate(oldFileInfoPair.Key, newNumLines, oldFileInfoPair.Value)) { OutputFunction.Invoke($"Changed: {fileInfo.Name}, {newNumLines - oldFileInfoPair.Value}"); } } // new file else { if (oldFileInfoPair.Key?.Name != fileInfo.Name && FileLineMap.TryAdd(fileInfo, newNumLines)) { OutputFunction.Invoke($"Created: {fileInfo.Name}, {newNumLines}"); } } } // no need to wait for this Task.Factory.StartNew(RemoveDeletedFiles, CancellationToken); }, CancellationToken)); }