Sto sviluppando un'applicazione che legge i file excel dal disco e quindi elabora i test in base ai dati nei file. Per mantenere l'interfaccia utente bloccata durante il caricamento di file e l'esecuzione di test, ho implementato async / await con Task.Run () per gestire carichi e test in esecuzione. Al momento ho solo un test e tre file di input, ma voglio assicurarmi che questa applicazione sia scalabile come il numero di file e amp; i test aumentano Le altre mie preoccupazioni non stanno assorbendo troppa potenza di elaborazione avendo troppi thread e potendo riportare lo stato di avanzamento dei carichi e dei test dei file. Ho implementato correttamente async / await / Task.Run per soddisfare questi dubbi?
private async void ProcessTestsAsync()
{
try
{
//TestFactory testFact = new TestFactory();
if (WorkingDirectory != null && (from f in Files where f.Location == "" select f).FirstOrDefault() == null)
{
// Load Files
var loadResults = await LoadFilesAsync();
// Run Tests
if (loadResults)
{
var testResults = await RunTestsAsync();
if (testResults)
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show("Failure");
}
}
else
{
MessageBox.Show("File Load Failed. Please check your files and try again.");
}
}
else
{
MessageBox.Show("One or more files has not been selected. Please choose any missing files and try again.");
}
}
catch (Exception err)
{
MessageBox.Show("Tests failed. Please try again. Error: " + err.Message);
}
}
private async Task<bool> RunTestsAsync()
{
try
{
using (var sem = new SemaphoreSlim(MAX_THREADS)) // Limit the number of threads that can run at a time
{
TestFactory testFact = new TestFactory();
var tasks = new List<Task>();
foreach (Model.Test test in IncludedTests)
{
await sem.WaitAsync();
tasks.Add(Task.Run(() =>
{
SortedList<Enums.FileType, DataTable> sources = new SortedList<Enums.FileType, DataTable>();
foreach (Enums.FileType fileType in test.ExpectedSources)
{
sources.Add(fileType, _files[fileType]);
}
test.Progress = 25;
TestBase t = testFact.getTest(test.Type);
if (t.SetWorkingDirectory(WorkingDirectory))
{
test.Progress = 50;
if (t.SetSources(sources))
{
test.Progress = 75;
if (t.RunTest())
{
test.Progress = 100;
}
}
}
else
{
MessageBox.Show("Test Failed.");
}
}));
}
await Task.WhenAll(tasks);
}
return true;
}
catch (Exception)
{
return false;
}
}
private async Task<bool> LoadFilesAsync()
{
try
{
_files.Clear();
using (var sem = new SemaphoreSlim(MAX_THREADS))
{
var tasks = new List<Task>();
foreach (var file in Files)
{
await sem.WaitAsync(); // Limit the number of threads that can run at a time
tasks.Add(Task.Run(() =>
{
file.FileLoadStatus = Enums.FileLoadStatus.InProgress;
_files.Add(file.Type, file.Source.LoadRecords(file));
file.FileLoadStatus = Enums.FileLoadStatus.Completed;
}));
}
await Task.WhenAll(tasks);
}
return true;
}
catch (Exception)
{
return false;
}
}