明确使用函数求<任务>异步lambda函数时动作过载可用 [英] Explicitly use a Func<Task> for asynchronous lambda function when Action overload is available

查看:103
本文介绍了明确使用函数求<任务>异步lambda函数时动作过载可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的一些C#5的异步的陷阱的博客文章读/等待。它提到在疑难杂症#4的东西是相当深刻,而且我从来没有想到过的。

简而言之,它涵盖了,你必须有两个重载的方法,一种采用了动作和一个带有一个 Func键和LT的场景;任务> (例如 Task.Run )。这个问题的根源在于论点,即异步无效方法应仅用于事件处理程序,与当时的帖子怎么回事描绘以下场景 - 这是什么编译器推断时像下面这样的lambda函数可以被编译到A Func键<任务> 动作

  Task.Run(异步()=> {
  等待Task.Delay(1000);
});

由于 Task.Run Task.Run(Func键<任务>)两个签名 Task.Run(动作),是什么类型的异步匿名函数编译成?一个异步无效 Func键<任务> ?我的直觉说,这将编译下降到异步无效纯粹是因为它是一个非泛型类型,不过C#编译器可能是聪明的,并给 Func键<任务> 类型preference

此外,有没有一种方法来明确声明其过载我希望用?我知道我可以只创建一个新的实例 Func键<任务> 和异步lambda函数传递有,但它仍然编译降到异步无效,然后传递到 Func键&LT的构造;任务> 。什么是确保理想的途径其编译为 Func键<任务>


解决方案

我只是检查它被编译成 Task.Run(Func键<任务>)默认,我没有很好的解释这一点。

下面为IL的相关部分

  IL_0001:ldsfld UserQuery.CS $<> 9__CachedAnonymousMethodDelegate1
IL_0006:brtrue.s IL_001B
IL_0008:ldnull
IL_0009:ldftn UserQuery<主> b__0
IL_000F:newobj System.Func< System.Threading.Tasks.Task> ..男星//< - 注意,在这里
IL_0014:stsfld UserQuery.CS $<> 9__CachedAnonymousMethodDelegate1
IL_0019:br.s IL_001B
IL_001B:ldsfld UserQuery.CS $<> 9__CachedAnonymousMethodDelegate1
IL_0020:拨打System.Threading.Tasks.Task.Run

您可以检查这一点很容易使用Visual Studio的类型推断,它会告诉你它会被编译什么方法,如果你只需将鼠标悬停的方法,或点击方法preSS <大骨节病> F12 你可以看到它的元数据会告诉你什么是由编译器推断类型。


  

此外,有没有一种方法来明确声明其过载我想
  使用?
  是的,明确指定委托。


  Task.Run(新动作(异步()=&GT;
{
    等待Task.Delay(1000);
}));Task.Run(新Func键&LT;任务&GT;(异步()=&GT;
{
    等待Task.Delay(1000);
}));

Reading over this blog post on some of the gotchas of C#5's async/await. It mentions in Gotcha #4 something that is quite profound and that I hadn't thought of before.

Briefly, it covers the scenario where you have a method that has two overloads, one that takes an Action and one that takes a Func<Task> (for example Task.Run). This issue is rooted in the argument that async void methods should only be used for event handlers, with the post then going on to portray the following scenario - What does the compiler infer when a lambda function like the following can be compiled to both a Func<Task> and an Action:

Task.Run(async () => {
  await Task.Delay(1000);
});

Because Task.Run has signatures of both Task.Run(Func<Task>) and Task.Run(Action), what type is the async anonymous function compiled to? An async void or a Func<Task>? My gut feeling says it will compile down to an async void purely because its a non-generic type however the C# Compiler might be smart and give Func<Task> types preference.

Also, is there a way to explicitly declare which overload I wish to use? I know I could just create a new instance of Func<Task> and pass in the async lambda function there but it would still compile down to a async void and then pass that into the constructor of the Func<Task>. What is the ideal way to make sure its compiled as a Func<Task>?

解决方案

I just checked it gets compiled into Task.Run(Func<Task>) by default, I don't have good explanation for this.

Here is the relevant part of IL

IL_0001:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_0006:  brtrue.s    IL_001B
IL_0008:  ldnull      
IL_0009:  ldftn       UserQuery.<Main>b__0
IL_000F:  newobj      System.Func<System.Threading.Tasks.Task>..ctor//<--Note here
IL_0014:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_0019:  br.s        IL_001B
IL_001B:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_0020:  call        System.Threading.Tasks.Task.Run

you can check this easily using visual studio type inference, it will show you what method it will be compiled if you just place mouse over the method, or just click the method press F12 you can see the metadata which will tell you what was the type inferred by compiler.

Also, is there a way to explicitly declare which overload I wish to use? Yes, Specify the delegate explicitly.

Task.Run(new Action(async () =>
{
    await Task.Delay(1000);
}));

Task.Run(new Func<Task>(async () =>
{
    await Task.Delay(1000);
}));

这篇关于明确使用函数求&LT;任务&GT;异步lambda函数时动作过载可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆