在同步方法内使用异步委托。

huangapple go评论68阅读模式
英文:

Use async delegate inside synchronous method

问题

我对这种情况下的基本行为不太确定:

public void Test()
{
    Method(async () => await Task.Delay(10000));
}

public void Method(Action action)
{
    action();
}

创建的委托使用了 async/await 机制,但在 Method 内部,action 同步调用,甚至没有办法以异步方式调用它,因为该委托不返回 Task。那么为什么能够为这个委托生成异步定义呢?乍一看,似乎只有像这样的代码才应该被允许:

Method(() => Thread.Sleep(10000));

我错过了什么吗?

英文:

I'm quite not sure about underlying behavior in this case:

    public void Test()
    {
        Method(async () => await Task.Delay(10000));
    }

    public void Method(Action action)
    {
        action();
    } 

A created delegate uses async/await machinery, but inside Method, action is called synchronisly and even there is no way to call it in async manner since this delegate doesn't return Task. So why it's even possible to generate async definition for this delegate? At first glance, only code like:

    Method(() => Thread.Sleep(10000));

should be allowed. What did I miss?

答案1

得分: 2

您的lambda表达式正在转换为一个没有返回值的async void方法。您可以通过编写以下方式来证明这一点:

static async void Foo()
{
}

static async Task Bar()
{
}

public void Test()
{
    Method(Foo);  //有效
    Method(Bar);  //编译错误
}

这意味着它将作为“fire and forget”调用运行。

值得注意的是,除非特定情况,最好避免使用async void。请参阅这个答案

英文:

Your lambda expression is being converted into an async void method which has no return value. You can prove this by writing it out:

static async void Foo()
{
}

static async Task Bar()
{
}

public void Test()
{
    Method(Foo);  //Works
    Method(Bar);  //Compilation error
}

This means it will run as a "fire and forget" call.

It's worth noting that async void is best avoided except for specific cases. See this answer.

huangapple
  • 本文由 发表于 2023年6月1日 05:31:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377428.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定