1

I have a .net webapi that has some code to send emails.

public async Task CheckOut(CheckOutData checkOutData){
     ...
     ...
     ...
     //What are the risks if I remove the await
     await SendEmail(checkOutData);
     ...
     ...
}

public async Task SendEmail(CheckOutData checkOutData)
{
  try{
  ...
  ...
  ...
  }
  catch (exception ex){
     //log Error
  }
}

I have setup logging in the SendEmail code. My question is, if I remove the await, is it possible for the thread to be killed and the email not being sent if the execution completes before the SendEmail completes?

Am I safe if I remove the await? I am willing to accept that an exception will be swallowed, it will be logged.

David
  • 5,403
  • 15
  • 42
  • 72
  • 1
    You'll get a Task back, it won't run unless you explicitly tell it to run. – Hans Passant Nov 25 '21 at 13:37
  • @HansPassant interesting, do you have any proof to support this? [The docs](https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap#task-status) seem to imply that all the tasks returned should already be in started enough state. – orhtej2 Nov 25 '21 at 15:38
  • After reading [this document](https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap) and its subpages I can find no downside other than exceptions being swallowed. But I'm not confident enough to claim this is the correct answer. – orhtej2 Nov 25 '21 at 15:46

1 Answers1

1

The email will be sent unless the entire process stops.

Regarding threads, we can divide SendEmail to two parts:

SendEmail
   // Code that will run on the calling thread. This is the code that will prepare the data and send it to the hardware.
   // Code that will run on a thread-pool thread. This is the  code that will run after the hardware will finish sending the message.

The first part of the method will hold the original thread so the thread will not be released before it will finish. The second part will run on a thread-pool thread so it doesn't matter if the original thread was released.

EDIT: If you are hosting your application on IIS, the app domain maybe recycled so it's not advised to run code that last the request. It's described in this blog post https://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html

In the self-hosting case this feature doesn't exist (Application pool recycling with Selfhosting a ASP.NET application). So you can just run a long running process by using Task.Run Long running task in ApiController (using WebAPI, self-hosted OWIN)

So in the self hosting case you can avoid the await. The part of your method that you won't wait for won't be killed. As in the Task.Run case described above.

Hope this helps

YanivR
  • 61
  • 5