Cause of TaskCanceledException with SendMailAsync?
The difference between your two method calls is that the former asynchronously waits using await
when being invoked. Thus, the TaskCanceledException
propagates from the inner SendEmailAsync
call, which is caused by the fact that you're not awaiting the async method in the using
scope, which causes a race condition between the disposal of SmtpClient
and the end of the async call. While in the latter, the exception is being encapsulated inside the return Task
object, which I'm not sure whether you're awaiting on or not. That's why in the former, you see the exception immediately.
The first thing that should be done is to properly await on SendEmailAsync
inside the gateway:
public class SmtpEmailGateway : IEmailGateway
{
public async Task SendEmailAsync(MailMessage mailMessage)
{
using (var smtpClient = new SmtpClient())
{
return await smtpClient.SendMailAsync(mailMessage);
}
}
}
Then, you can use the second method which avoids the overhead of creating the state-machine. The difference is now you're guaranteeing that SmtpClient
will only dispose once the async operation completes.