Because the lambda expression is asynchronous, it can be executed on any thread that calls Value, and the expression will run within the context.
The lambda can be run from any thread (unless you're careful about what types of threads you let access the value of the Lazy
), and as such it will be run in the context of that thread. That's not because it's asynchronous, it would be true even if it was synchronous that it'd run in the context of whatever thread happens to call it.
As i understand it, the Thread come to FetchPerson and is stuck in Lamda execution.
The lambda is asynchronous, as such it will (if implemented properly) return almost immediately. That's what it means to be asynchronous, as such it won't block the calling thread.
Is that realy bad? What consequences?
If you implement your asynchronous method incorrectly, and have it doing long running synchronous work, then yeah, you're blocking that thread/context. If you don't, you aren't.
Additionally, by default all of the continuations in your asynchronous methods will run in the original context (if it has a SynchonrizationContext
at all). In your case your code almost certainly doesn't rely on re-using that context (because you don't know what contexts your caller might have, I can't imagine you wrote the rest of the code to use it). Given that, you can call .ConfigureAwait(false)
on anything that you await
, so that you don't use the current context for those continuations. This is simply a minor performance improvement in order to not waste time scheduling work on the original context, waiting for anything else that needs it, or making anything else wait on this code when unnecessarily.
As a solution, the author suggest to create a Task: [...] Is that really correct?
It won't break anything. It will schedule the work to run in a thread pool thread, rather than the original context. That's going to have some extra overhead to start with. You can accomplish approximately the same thing with lower overhead by simply adding ConfigureAwait(false)
to everything that you await
.
This is an IO operation, but we steal CPU thread from Threadpool.
That snippet will start the IO operation on a thread pool thread. Because the method is still asynchronous it will return it to the pool as soon as it starts it, and get a new thread from the pool to start running again after each await. The latter is likely appropriate for this situation, but moving the code to start the initial asynchronous operation to a thread pool thread is just adding overhead for no real value (because it's such a short operation you'll spend more effort scheduling it on a thread pool thread than just running it).