I am trying to read the contents of a directory that has over 100k+ files. Each file will be parsed eventually. Since this is a long time consuming task I want to provide feedback to the end user that the program has not "frozen", This is an MVP pattern project setup.
I am using async Task and IProgress to provide feedback to the UI, but either methods below lock up the UI and I can't figure out why..
private async void MainFormViewOnStartProcessingFiles(object sender, EventArgs eventArgs)
{
// The Progress<T> constructor captures our UI context,
// so the lambda will be run on the UI thread.
var asyncProgress = new Progress<int>(percent =>
{
EventAggregator.Instance.Publish(new DisplayMainFormWaitBarMessage($"Async found {percent} files..."));
});
// GetDirectoryFiles is run in the thread pool
await Task.Run(() => GetDirectoryFilesAsync(asyncProgress));
var syncProgress = new Progress<int>(percent =>
{
EventAggregator.Instance.Publish(new DisplayMainFormWaitBarMessage($"Sync found {percent} files..."));
});
GetDirectoryFiles(syncProgress);
}
This updates the UI
private void DisplayWaitingBarMessage(DisplayMainFormWaitBarMessage obj)
{
_mainFormView.DisplayWaitBarMessage(obj.DisplayText);
}
This is my Async and Non Async code to read the files into a queue
private async Task GetDirectoryFilesAsync(IProgress<int> taskProgress)
{
await Task.Run(() =>
{
try
{
var directoryPath = Directory.GetCurrentDirectory() + @"\..\..\..\FUG_2017\";
var _listOfDirectoryFiles = Directory.GetFiles(directoryPath).Take(100);
var fileCount = 0;
foreach (var filePath in _listOfDirectoryFiles)
{
_filesToProcessQueue.Enqueue(filePath);
fileCount++;
taskProgress?.Report(fileCount);
}
}
catch (Exception exc)
{
FlushAndExit(exc);
}
});
}
private void GetDirectoryFiles(IProgress<int> taskProgress)
{
try
{
var directoryPath = Directory.GetCurrentDirectory() + @"\..\..\..\FUG_2017\";
EventAggregator.Instance.Publish(new DisplayMainFormWaitBarWithMessage(ElementVisibility.Visible, $"Inspecting path {directoryPath}"));
var _listOfDirectoryFiles = Directory.GetFiles(directoryPath).Take(1000);
var fileCount = 0;
foreach (var filePath in _listOfDirectoryFiles)
{
_filesToProcessQueue.Enqueue(filePath);
fileCount++;
EventAggregator.Instance.Publish(new DisplayMainFormWaitBarWithMessage(ElementVisibility.Visible, $"Loaded file {fileCount} of {_listOfDirectoryFiles.Count()} to Queue..."));
taskProgress?.Report(fileCount);
}
EventAggregator.Instance.Publish(new DisplayMainFormWaitBarWithMessage(ElementVisibility.Visible, $"Loaded {_listOfDirectoryFiles.Count()} files to Queue..."));
}
catch (Exception exc)
{
FlushAndExit(exc);
}
}