Reputation: 4575
Let us say, I have a call like this:
await Task.Run(async() => SomeLongRunningNonAsyncMethod());
My understanding is when SomeLongRunningNonAsyncMethod() is called, the call doesn't return until it encounters await. But there is no await in SomeLongRunningNonAsyncMethod().
So, is this same as direct SomeLongRunningNonAsyncMethod() call?
Upvotes: 0
Views: 187
Reputation: 149618
My understanding is when
SomeLongRunningNonAsyncMethod()
is called, the call doesn't return until it encounters await. But there is no await inSomeLongRunningNonAsyncMethod()
.
You need to distinguish between the delegate
you pass to Task.Run
and the actual execution of Task.Run
The former will execute synchronously inside a ThreadPool
thread. You dont need to use the async
keyword as you are not awaiting on any async operation inside the given delegate.
The latter will hit its await
when Task.Run
begins to execute and yield control back to the calling method until the delegate finishes execution.
So, is this same as direct SomeLongRunningNonAsyncMethod() call?
No. A direct call would execute synchronously on the current running thread. Your code executes the delegate synchronously on a ThreadPool
thread, meanwhile the thread the call to Task.Run
awaits the completion of the Task
in a non-blocking fashion.
Your code should actually be:
await Task.Run(SomeLongRunningNonAsyncMethod);
Upvotes: 3
Reputation: 158379
The await
keyword will cause control to be returned to the calling method as soon as the call to Task.Run
returns. That call returns "immediately" (it will only schedule the operation using the current task scheduler, not wait for it to complete). Once the task is completed, the code following the await
line will continue executing.
Upvotes: 0
Reputation: 63772
Your understanding is indeed flawed.
As the code execution gets to the await Task.Run
, it will first execute Task.Run
as usual (which will queue the method on the thread pool), and then return immediately. When the method inside the Task.Run
finishes, the execution will continue after the await
.
Whether this is useful or not depends heavily on your context. For example, if you're calling this from an event handler in a WinForms / WPF application, this is indeed a good way to avoid blocking the UI thread while doing some background work. If you're doing this in a web application, you're just causing a thread switch and a thread pool thread for no reason.
If you're doing I/O in the Task.Run
, rather than CPU work, you want to find an asynchronous API to do the same I/O work - this will save you the thread that would block anyway while the I/O request completes.
Upvotes: 2