作者:丶沈丨灬de艳本人 | 来源:互联网 | 2023-05-23 11:30
1> Stephen Clea..:
是什么导致编译器以不同于L1和L2的方式处理L3.为什么简单地将"async"添加到L1(或从L2中删除等待)会导致编译器对其进行不同的处理?
因为async
并且await
更改了lambda表达式中的类型.您可以将其async
视为"添加" Task<>
包装器,并将其await
视为"删除" Task<>
包装器.
只需考虑最里面调用中涉及的类型.首先,L1:
return Task.Run(() =>
{
return new Dummy();
});
() => { return new Dummy(); }
is 的类型Func
,以及该重载Task.Run
的返回类型是Task
.
所以() => ###Task###
is 的类型Func>
,调用不同的重载Task.Run
,返回类型为Task
.等等.
现在考虑L2:
return await Task.Run(async () =>
{
return new Dummy();
});
类型async () => { return new Dummy(); }
是Func>
,所以该重载Task.Run
的返回类型是Task
.
async () => await ###Task###
is 的类型Func>
,因此它调用结果类型为的相同重载Task.Run
Task
.等等.
最后,L3:
return Task.Run(async () =>
{
return new Dummy();
});
类型async () => { return new Dummy(); }
又是Func>
,所以该重载Task.Run
的返回类型是Task
.
类型async () => { return ###Task### }
是Func>>
.请注意嵌套任务.因此,再次调用相同的重载Task.Run
,但它的返回类型是Task>
这次.
现在,您只需重复每个级别.类型async () => { return ###Task>### }
是Func>>>
.在的同一超载Task.Run
被再次调用,但它的返回类型是Task>>
这个时候.等等.
如果您将更多Task.Run级联到L1/L2/L3,则Visual Studio会崩溃.我正在使用VS2013,如果我级联5层或更多层的Task.Run,它会崩溃.4层是我能得到的最好的,这就是为什么我使用4层作为我的例子.只有我吗 ?编译器在翻译Task.Run时会发生什么?
谁在乎?没有现实世界的代码可以做到这一点.众所周知的场景对于编译器来说在合理的时间范围内难以处理; 在方法重载解析中使用lambda表达式是其中之一.使用lambda表达式的嵌套调用使编译器的工作量指数级增加.