根据Task<T>.Result
的原始文档,它导致等待线程被阻止。
处方是在请求.Wait()
之前致电.Result
。
这仍然是真的吗?如果不是,它何时改变?
后续问题:在.Wait()
(仍然)有用或必要之前调用.Result
?
编辑:(更多背景/细节)
我这里可能有一个严重的概念错误。但据我所知......
调用.Wait()
会将任务返回给调度程序,并在任务完成后重新输入。有效地将车停在交叉路口中间(阻挡所有人)与停在路边,直到你准备继续行驶(而每个特别等待你的人也停在一边)。< / p>
Monitor,Semaphore等机制......将阻止&#39;阻止&#39;尝试访问资源的所有线程。可能会不必要地破坏您的表现。当我第一次遇到.Result
(在异步/等待之前)时,文档和支持信息表示它是“阻止”。这可能仍然是正确的。
我想知道的是:
1)我对.Wait()
的理解是否正确?它是否将任务交还给调度程序重新进入?它可能没有以前,但我猜测可以实现编译器优化以允许这样做。
2)以下是否有任何真正的区别:
只需致电.Result
。
var x = task.Result;
或在致电.Wait
之前致电.Result
?
task.Wait();
var x = task.Result;
答案 0 :(得分:1)
仅调用Result
和调用Wait()
后跟Result
之间没有区别。如果任务尚未完成,它们都直接依赖Task.InternalWait。
对于问题的第一部分 - Wait()
没有&#34;将任务返回给调度程序并重新输入&#34;之后,这正是await
的用途。等待阻止它运行的线程,直到任务完成。但听起来你关心互斥,而不是阻止,这是不同的。
阻塞意味着一个线程已经执行了一些代码,导致它等待其他事情发生。线程正在使用中,就好像它正在做实际工作一样,但是它什么都不做。这是不必要的浪费,特别是在Web应用程序这样的场景中,我们总是希望线程可用于执行代码来处理传入的请求,因为线程实际上是一种有限的资源,并且通常有等待使用不消耗的OS级设施的方法一个线程(这基本上是async/await
对你的正确使用)。但阻塞不会阻止其他线程在其中的一个线程内执行相同的代码。这是互斥,它明确地使用像Monitor或Semaphore这样的线程同步机制来限制或阻止在同一进程中多个线程之间对一段代码的并发访问。
Result
和Wait()
正在阻止,但不会执行任何形式的互斥。