I have a windows forms application in which I send an email using SmtpClient. Other async operations in the application use async/await, and I'd ideally like to be consistent in that when sending the mail.
I display a modal dialog with a cancel button when sending the mail, and combining SendMailAsync with form.ShowDialog is where things get tricky because awaiting the send would block, and so would ShowDialog. My current approach is as below, but it seems messy, is there a better approach to this?
private async Task SendTestEmail()
{
  // Prepare message, client, and form with cancel button
  using (Message message = ...)
  {
     SmtpClient client = ...
     CancelSendForm form = ...
     // Have the form button cancel async sends and
     // the client completion close the form
     form.CancelBtn.Click += (s, a) =>
     {
        client.SendAsyncCancel();
     };
     client.SendCompleted += (o, e) =>
     {
       form.Close();
     };
     // Try to send the mail
     try
     {
        Task task = client.SendMailAsync(message);
        form.ShowDialog();
        await task; // Probably redundant
        MessageBox.Show("Test mail sent", "Success");
     }
     catch (Exception ex)
     {
        string text = string.Format(
             "Error sending test mail:\n{0}",
             ex.Message);
        MessageBox.Show(text, "Error");
     }
  }   
 
     
    