Reputation: 89
According to the original documentation for Task<T>.Result
, it caused waiting threads to be blocked.
The prescription was to call .Wait()
before requesting .Result
.
Is this still true? If not, when did it change?
Subsequent question: is calling .Wait()
before .Result
(still) helpful or necessary?
EDIT: (more context/detail)
I may have a gross conceptual error here. But as I understand it...
Calling .Wait()
will return a task to the scheduler and re-enter once the task is complete. Effectively the difference between parking your car in the middle of an intersection (blocking everyone) vs stopping on the side of the road until you're ready to move on (while everyone specifically waiting for you also parks on the side).
Mechanisms like Monitor, Semaphore, etc... Will 'block' all threads that attempt to gain access to a resource. Potentially killing your performance unnecessarily. When I first encountered .Result
(before async/await) the documentation and supporting information said it was 'blocking'. Which is likely still true.
What I'm wondering is:
1) Is my understanding of .Wait()
correct? Does it give the task back to the scheduler for re-entrance? It may not have before, but I'm guessing that a compiler optimization could have been implemented to allow this.
2) Is there any real difference between the following:
Just calling .Result
.
var x = task.Result;
Or calling .Wait
before calling .Result
?
task.Wait();
var x = task.Result;
Upvotes: 0
Views: 837
Reputation: 6514
There is no difference between just calling Result
and calling Wait()
followed by Result
. Both of them rely directly on Task.InternalWait if the task is not yet completed.
For the first part of your question - Wait()
does not "return a task to the scheduler and re-enter" later, that's exactly what await
is for. Waiting blocks the thread it's running on until the task is complete. But it sounds like you are concerned about mutual exclusion, as opposed to blocking, which is something different.
Blocking means that a thread has executed some code that is causing it to sit and wait for something else to happen. The thread is in use, just as if it was doing real work, but it's sitting doing nothing. This is needlessly wasteful, especially in scenarios like web applications where we always want to have threads available to execute code to handle incoming requests, because threads are effectively a finite resource and there are often ways to wait using OS-level facilities that do not consume a thread (this is essentially what proper use of async/await
does for you). But blocking does not prevent other threads from executing the same code while one thread is inside of it. That is mutual exclusion, which explicitly uses thread synchronization mechanisms like Monitor or Semaphore to limit or prevent concurrent access to a section of code among multiple threads in the same process.
Result
and Wait()
are blocking, but do not perform any kind of mutual exclusion.
Upvotes: 1