I have four tasks to run within the MainViewModel of a C# WPF Windows Application. All the tasks call the same Update method, using a different parameter value for each execution. I call the Update method in the MainViewModel like this:
//UpdateStatus is another method in the MainViewModel (see below)
var progress = new Progress<string>(data => UpdateStatus(data));
var tasks = new List<Task>();
//There are some DataTables that I have summarised here to have names that start with "dt_" as seen below
tasks.Add(Task.Run(() => FileSchema_Tradacom_tab = FileSchema.Update_FileSchema(dt_T, FileStyle.Tradacom, progress)));
tasks.Add(Task.Run(() => FileSchema_Edifact_tab = FileSchema.Update_FileSchema(dt_E, FileStyle.EdiFact, progress)));
tasks.Add(Task.Run(() => FileSchema_DepotList_tab = FileSchema.Update_FileSchemac(dt_D, FileStyle.DepotList, progress)));
tasks.Add(Task.Run(() => FileSchema_ProductList_tab = FileSchema.Update_FileSchema(dt_P, FileStyle.ProductList, progress)));
await Task.WhenAll(tasks);
[... code continues...]
Inside the method, the FileStyle
parameter is used to report back the status for that execution.
public static DataTable Update_FileSchema(DataTable dt, FileStyle fileStyle,IProgress<string> progress)
{
progress.Report($"1[{StatusCode.Connecting}]Connecting...");
[...Code to retrieve data from csv files and SQL queries...]
//note the use of the fileStyle parameter to add detail
progress.Report($"0[{StatusCode.Connected}]File Schema ({fileStyle}) Retrieved");
}
finally, the method that Updates the Status Pane on my application window looks like this is also in the MainViewModel
private void UpdateStatus(string message)
{
//Sets the values of various properties of the MainViewModel, including Status and StatusMessage,
//Which are displayed in a WPF TextBlock
if (message.Contains("]"))
{
try
{
this.Status = this.Status ?? "";
//The message comes after the bit in square brackets
var newMessage = $"{(Status.Length == 0? "":"
")}{message.Substring(message.IndexOf("]") + 1)}";
//The new line indicator (1 or 0) comes before the square brackets
var addLine = message.Substring(0, message.IndexOf("[")) == "1";
//The code is the bit inside the square brackets (gotta get the start and end points of this one)
var codeFrom = message.IndexOf("[") + 1;
var codeTo = message.LastIndexOf("]");
var codeValue = message.Substring(codeFrom, codeTo - codeFrom);
this.StatusCode = (StatusCode)Enum.Parse(typeof(StatusCode), codeValue);
[...More code that goes on to update other properties of this MainViewModel...]
}
I had hoped when running this to see four identifiably different reports in the application status window, reporting each of the four tasks. Instead, although I get four reports but they all say the same thing - I see "File Schema (DepotList)" repeated four times.
If I add a Thread.Sleep(10000);
between the two reports in the Update method, I see that each of the statuses is updating correct line in the Status Pane Textblock in that when it is not adding a new line, it replaces the correct "Connecting..." line that was inserted earlier in the method execution.
I don't understand why the reporter is not taking the different values of the fileStyle parameter and spitting them back out in the progress report; surely each concurrent execution of the method runs separately with separate values in the parameter? In fact I see that this is the case when I run a SQL Profiler, I see four separate queries being made each with a different fileStyle! Any pointers would be extremely welcome.
question from:
https://stackoverflow.com/questions/65845081/async-method-not-reporting-back-correctly-from-list-of-tasks