async lambda不会产生预期的结果

时间:2014-12-17 14:59:35

标签: c# .net lambda async-await c#-5.0

我有这段代码:

static void Main(string[] args)
{
    Func<Task<string>> getWordAsync = async () => "hello";

    Console.WriteLine(getWordAsync());

    Console.ReadLine();
}

取自this本书。如果不打印:

"hello"

而不是:

System.Threading.Tasks.Task`1[System.String]

2 个答案:

答案 0 :(得分:4)

要获取async功能的结果,您需要使用await关键字。另一个选项是获取Result对象的Task属性。

答案 1 :(得分:4)

不要躲在幕后!

async / await关键字实际上不是公共语言规范的一部分(CLR所基于的),但它是编译器的工件。编译器将您的lambda重写为NOT不返回字符串,但实际上返回Task<string>。您应该能够清楚地看到这一点,因为

() => "hello" 

Func<string>,它在执行时返回System.String,而您的变量的类型为

Func<Task<string>>

或者,Func<T>执行时会返回Task<string>

因此,当您执行func时,返回结果为

System.Threading.Tasks.Task`1[System.String]

(Task`1 [System.String]是泛型类型输出其通用参数的示例)

所以,行

Console.WriteLine(getWordAsync());

Task<string>类型的对象上调用ToString(),该对象打印出类型的名称。这是预期的。

任务实际上是在不同的线程上运行,因此您需要执行以下操作之一来获取任务的结果:

Console.WriteLine(await getWordAsync());

(在使用此版本之前,您必须将主要方法标记为async)或

Console.WriteLine(getWordAsync().Result);

第二个将阻塞当前线程,直到结果可用。第一个将在结果可用时在不同的线程上执行Console方法。那是async / await兔子洞的又一步,顺便说一下。