Task.Run
method queues the specified work to run on the ThreadPool
, according to MSDN. The Task.Wait
method is blocking one. The simple explanation of this can be found in this article
Even if the underlying task is asynchronous, if you call a blocking
method or blocking property on the task, execution will wait for the
task to complete - but will do so synchronously, such that the current
thread is completely occupied during the wait. So, if you use one of
the above properties/methods, be sure that's actually what you meant
to do.
So, you current thread (which executes RunLongTask().Wait();
) will be blocked until work inside this Task
is completed synchronously
Task.Run(()=>{
// Run some Synchronous long IO process
}
There is no doubling of running the synchronous code directly, your main thread is just blocked and waiting until I/O process is completed on a separate thread
Also would 2 threads always be created in this case due to the double blocking?
You already have at least one Thread
, the current one, which is calling Task.Run
. Task.Run
will obtain a free worker thread from thread pool (if any of them), but it will be a different thread.
In terms of performance running the I/O operation on a separate thread isn't very efficient (as it can be for CPU bound work), because the worker thread will mostly be waiting for sending/receiving the data. It's better to make your long IO process asynchronous and run it without blocking (if it supports asynchronous APIs, of course).
Another potential performance drawback is that ASP.NET Core uses one thread per request and running a background thread with long running IO process will reduce the number of threads available to handle new requests (and scalability of your application as well)