What is the difference between calling task-returning method directly and warping the task-returning method with Task.Run?

Viewed 76

I know that Task.Run will get a thread from threadpool to run that method, beside that why in the following code it needs to warp the task-returning method with Task.Run.

I am referring to the https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md

GOOD Task-returning methods are better since unhandled exceptions trigger the TaskScheduler.UnobservedTaskException.

public class MyController : Controller
{
    [HttpPost("/start")]
    public IActionResult Post()
    {
     *//this line, why wrap it in Task.Run
        Task.Run(BackgroundOperationAsync);*
        return Accepted();
    }
    
    public async Task BackgroundOperationAsync()
    {
        var result = await CallDependencyAsync();
        DoSomething(result);
    }
}
2 Answers

beside that why in the following code it needs to warp the task-returning method with Task.Run.

There isn't a good reason. Since this is ASP.NET Core, the code is roughly equivalent to

_ = BackgroundOperationAsync();

The primary point that the example is trying to make is to avoid async void and to use async Task instead (for BackgroundOperationAsync). However, the specific example I think is problematic because doing fire-and-forget on ASP.NET Core at all is not what I would ever call a "GOOD" solution; while async Task is marginally better than async void, neither are "good" solutions.

One possible reason is to make sure the entire method runs on a separate thread. If you just called it directly, the part before the first await would run on the current thread.

In this particular example there is no code before the first await, but I think the idea is there could be.

Related