Async方法即使被调用也不会执行

本文关键字:执行 调用 方法 Async | 更新日期: 2023-09-27 18:13:34

我的工作流:构造函数->调用async方法1 ->调用async方法2 ->调用async方法3

构造函数:

public MyConstructor() {
    Method1();
}

Method1:

private async void Method1() {
    //do some stuff
    await Method2();
    //do some more stuff
}
方法2:

protected internal async Task Method2() {
    //do some stuff
    var x = await Method3("someParams");
    //do some more stuff
}
方法3:

public async Task<List<string>> Method3(string someParams) {
    Debug.WriteLine("I am here"); //Breakpoint doesn't get hit, no output "I am here"
}

是的,我知道,你可能想知道为什么我使用这么多不同的异步方法。但是还有更多的事情在发生(但是没有什么影响到这个问题!)问题是,Debug.WriteLine("I am here");没有被命中,也没有抛出异常。

我做错了什么?

Async方法即使被调用也不会执行

简而言之:是的,正如@fknx在评论中提到的,问题是代码异步执行,没有等待,因此应用程序在到达有问题的行之前退出。

在你的例子中有几个不好的做法:

async void方法

创建这样的东西不是一个好主意,因为你失去了对任务的跟踪。请始终定义Task作为返回值,它不花费任何东西,它将帮助您编写正确的API。

构造函数中

异步调用

这也不是一个好的设计,因为(正如你提到的)你不能在构造函数中等待这个方法,所以你只会启动任务并丢失它。请考虑使用async Init方法。

所以不用这个:

public class MyCustomClass
{
    public MyCustomClass()
    {
        // BAD CODE, do not do this
        Method1();
    }
    private async Task Method1()
    {
        //do some stuff
        await Method2();
        //do some more stuff
    }
}

你可以这样做:

class Program
{
    static void Main(string[] args)
    {
        var m = new MyCustomClass();
        m.InitializeAsync().Wait();
        Console.WriteLine("Before exit...");
    }
}
public class MyCustomClass
{
    public MyCustomClass()
    {
        // in a constructor you should not do anything async
    }
    public async Task InitializeAsync()
    {
        await Method1();
    }
    private async Task Method1()
    {
        //do some stuff
        await Method2();
        //do some more stuff
    }
}

在主方法中等待异步方法绝对是OK的,或者准确地说,如果你想创建一个真正的异步应用程序,你的控制台应用程序应该在主方法(而不是其他地方)中只有一个Wait(或WaitAll,或其他)方法。