var task = Task.Run(() => DoSomeStuff()).Result;
引擎盖下面发生了什么?
我做了一个小小的测试:
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var r = Task.Run( () => {Thread.Sleep(5000); return 123; }).Result;
Console.WriteLine(r);
}
}
5秒后打印“ 123”。那么访问Task
上的任何此类属性是否充当调用Task.Wait()
的快捷方式,即这样做安全吗?
[以前我的代码叫Task.Delay(5000)
,它立即返回“ 123”。我已在问题中解决此问题,但在此保留评论和答案以供参考。
那么访问
Task
上的任何此类属性是否充当调用Task.Wait()
的快捷方式?
是
来自the docs:
访问[
Result
]属性的get访问器将阻塞调用线程,直到异步操作完成为止;它等效于调用Wait方法。
但是,您的测试并未达到您认为的目的。
Task.Delay(..)
返回Task
,该时间在指定的时间后完成。它不会阻塞调用线程。
因此() => { Task.Delay(5000); return 123; }
只需创建一个新的Task
(将在5秒钟内完成),然后将其丢弃并立即返回123
。
您可以:
Task.Delay(5000).Wait()
来阻止调用线程(与Thread.Sleep(5000)
相同)Task
返回的Task.Delay
完成:Task.Run(async () => { await Task.Delay(5000); return 123; })
测试不等待Task.Delay()
,因此它会立即返回。应该是:
var r = Task.Run(async () => { await Task.Delay(5000); return 123; }).Result;
Result
的行为已得到很好的定义-如果任务尚未完成,它将阻塞直到它完成为止。访问其他任务属性不会被阻止