I am trying to run a task in a method and have the method return a value. The reason I am using a task is because I need progress reporting.
This was my original strategy
private async void CallLongRunningTask()
{
string fileName = "TestFN";
Progress<string> progress = new Progress<string>();
progress.ProgressChanged += (_, newText) => lbl.Text=newText;
bool retVal = await Task.Run(() => LongRunningTask(fileName, progress));
Task.WaitAll();
// do some other stuff
}
public bool LongRunningTask(string fn, IProgress<string> progress)
{
// long running task with progress report
while (i < 100000000)
{
i++;
if (i % 10000 == 0)
{
progress.Report("Processing "+i.ToString());
}
}
return true;
}
As expected, it blew through the WaitAll, went back to the prior method.
So, I tried this:
got rid of async in the signature
bool retVal = Task.Run(() => LongRunningTask(fileName, progress));
bool retVal = Task.Run(async () => LongRunningTask(fileName, progress));
Both instances, I lost my progress.
So I tried to change my calling program:
Task.Run(() => CallLongRunningTask()).Wait();
That broke my progress reporting because my progress reporting updates a label on the form so there was some kind of cross thread contamination.
I have read and tried all the relevant similar problems/solutions. This seems so simple but clearly I am missing something. The entire Task() and async thing seems to be on a level of abstraction that I can't seem to grasp no matter how many times I read Stephen Cleary's book.
Any thoughts or ideas or help in any way, would be greatly appreciated!
async void. It's only meant for event handlers. If you don't want to return a result useasync TaskTask.WaitAll()is meaningless.WaitAllwaits only for its arguments to complete but you didn't provide any. You don't need it either sinceawaitawaits for the task to complete. The problem is that the entire method is a fire-and-forget method due toasync voidWaitAllas already mentioned.