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!
There is no need for the WaitAll
as already mentioned.
private async Task CallLongRunningTask() {
string fileName = "TestFN";
Progress<string> progress = new Progress<string>();
progress.ProgressChanged += (_, newText) => lbl.Text=newText;
//waiting here for long running task to finish
bool retVal = await Task.Run(() => LongRunningTask(fileName, progress));
// do some other stuff after waiting
}
async-await spreads all the way up. You need to await everything including the calling method.
await CallLongRunningTask();
and so on.
If calling from an event handler, that is the only exception where async void
can be used
private async void OnSomeHandler(object sender, EventArgs args) {
//...
await CallLongRunningTask();
//...
}
Reference Async/Await - Best Practices in Asynchronous Programming
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.