简体   繁体   English

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

[英]Async method doesn't get executed even when it gets called

My workflow: Constructor -> Calls async Method 1 -> Calls async Method 2 -> Calls async Method 3我的工作流程:构造函数 -> 调用异步方法 1 -> 调用异步方法 2 -> 调用异步方法 3

Constructor:构造函数:

public MyConstructor() {
    Method1();
}

Method1:方法一:

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

Method 2:方法二:

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

Method 3:方法三:

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

Yeah I know, you probably wonder why I am using so many different async methods.. But there is some more stuff going on (but nothing that influences the problem!).是的,我知道,您可能想知道为什么我要使用这么多不同的异步方法......但是还有更多的东西在进行(但没有任何影响问题的东西!)。 The problem is, Debug.WriteLine("I am here");问题是, Debug.WriteLine("I am here"); does not get hit, and no exception is thrown.没有得到命中,并且不会引发任何异常。

What am I doing wrong?我做错了什么?

In a nutshell: yes, as @fknx mentioned in a comment, the problem is that the code executes asynchronously and is not awaited, therefore the app exits before reaching the line in question.简而言之:是的,正如@fknx 在评论中提到的,问题是代码异步执行并且没有等待,因此应用程序在到达相关行之前退出。

There are a couple of bad practices in your example:您的示例中有一些不好的做法:

async void method异步无效方法

It is not a good idea to create such things as you loose track of the task.创建这样的东西不是一个好主意,因为你会失去对任务的跟踪。 Please always define Task as the return value, it does not cost anything and it will help you write a correct API.请始终将Task定义为返回值,它不会花费任何费用,并且会帮助您编写正确的 API。

asynchronous call in a constructor构造函数中的异步调用

This is not a good design either, because (as you mentioned) you cannot await this method in a constructor so you will just fire up the task and loose it.这也不是一个好的设计,因为(正如你提到的)你不能在构造函数中等待这个方法,所以你只会启动任务并释放它。 Please consider using an async Init method instead.请考虑使用异步初始化方法。

So instead of this:所以而不是这个:

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
    }
}

You could do this:你可以这样做:

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
    }
}

It is absolutely OK to Wait for an async method in the Main method , or to be precise your console app should have only one Wait (or WaitAll, or whatever) method in the main method (and nowhere else) if you want to create a truly async app.这是绝对OK等待Main方法异步方法,或者更准确地说您的控制台应用程序只能一个等待(或为WaitAll,或者别的什么)方法的主要方法(和其他地方),如果你想创建一个真正的异步应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM