You don’t have to put the Task.Run
in DoWorkAsync
. Consider this option:
public async Task UIAction()
{
// UI Thread
Log("UIAction");
// start the CPU-bound work
var cts = new CancellationTokenSource(5000);
var workTask = Task.Run(() => DoWorkAsync(cts.Token));
// possibly await for some IO-bound work
await Task.Delay(1000);
Log("after Task.Delay");
// finally, get the result of the CPU-bound work
int c = await workTask;
Log("Result: {0}", c);
}
This results in code with much clearer intent. DoWorkAsync
is a naturally synchronous method, so it has a synchronous signature. DoWorkAsync
neither knows nor cares about the UI. The UIAction
, which does care about the UI thread, pushes off the work onto a background thread using Task.Run
.
As a general rule, try to “push” any Task.Run
calls up out of your library methods as much as possible.