Why Async Method always blocking thread?

后端 未结 4 1451
星月不相逢
星月不相逢 2021-01-29 02:38

I have a method async like this:

public static async Task SendMailAsync(){
...something
}

This method is very long time to return r

4条回答
  •  无人共我
    2021-01-29 03:12

    Adding the async method does not (by itself) make code asynchronous. Async code is hard - all that the async modifier does is enable the await keyword (and enable some compiler magic about the return type). If the method doesn't actually do anything asynchronous, it won't be asynchronous. In particular:

    • if a method doesn't await: it won't really be asynchronous in the async sense
      • (minor caveat there: if a method isn't marked async, and simply returns a Task[] from another method, then it might expose an asynchronous behaviour)
    • if a method does await, but all of the things being awaited always actually completed synchronously: it isn't truly asynchornous

    In this case, it is the first bullet. There is no await in the code. In fact, the compiler should already be giving you a warning about this:

    Warning CS1998 This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

    Even if a method returns Task[] (or some other awaitable pattern): if it isn't actually asynchronous (because of either of the bullets above): it will run to completion before it returns to the caller; and when it does so, it will be known as already complete.


    For this code to be asynchronous, something it does (presumably the send) would need to be asynchronous. Perhaps:

    foreach (var email in sendingList)
    {
        await MailHelper.SendMailAsync(email, subject, body);
        await Task.Delay(60 * 1000);
    }
    

    Note; if your MailHelper doesn't have an async API, you could also make it asynchronous just by making the delay asynchronous:

    foreach (var email in sendingList)
    {
        MailHelper.SendMail(email, subject, body);
        await Task.Delay(60 * 1000);
    }
    

    Final thought: hiding exception details is almost always bad.

提交回复
热议问题