7

I'm trying to send an SMS asynchronously from an MVC5 controller.

In the controller I call the following method, which is in another class. I don't need any response from the method and don't care if it fails.

    public async void SendSMS(string phoneNumber, string message)
    {
        await Task.Run(() =>
            {
                TwilioRestClient twilio = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
                twilio.SendSmsMessage(TWILIO_PHONE_NUMBER, phoneNumber, message);
            }
        );
    }

This isn't working for me, as it seems to be running synchronously. Any tips on how to improve the code and get it into working order are appreciated.

tereško
  • 58,060
  • 25
  • 98
  • 150
jed
  • 73
  • 1
  • 1
  • 4

1 Answers1

6

When you await a Task (or any other awaitable), you're telling the compiler "Im executing this task and yielding control back to you". What happends is that control is returned to the caller until the Task finishes execution, and the compiler generates a state machine that will return to the await once it completes.

In your method, you dont need any of that.

I will state that im not a fan of fire and forget methods and I think you should add a continuation to handle the Tasks failure even if you dont care if it succeeds. If you're using .NET 4.0 not handling a Task exception will cause your process to terminate when the finializer disposes the Task.

You can remove the async from your method signature since you dont need to await and return a Task instead:

public Task SendSMS(string phoneNumber, string message)
{
    return Task.Run(() =>
    {
        TwilioRestClient twilio = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
        twilio.SendSmsMessage(TWILIO_PHONE_NUMBER, phoneNumber, message);
    });
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321