I need to send an email as a result of a SignalR hub invocation. I don't want the send to execute synchronously, as I don't want to tie up WebSocket connections, but I would like the caller to be informed, if possible, if there were any errors. I thought I'd be able to use something like this in the hub (minus error handling and all other things that I want it to do):
public class MyHub : Hub {
public async Task DoSomething() {
var client = new SmtpClient();
var message = new MailMessage(/* setup message here */);
await client.SendMailAsync(message);
}
}
But soon discovered that it won't work; the client.SendMailAsync call throws this:
System.InvalidOperationException: An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle.
Further investigation and reading has shown me that SmtpClient.SendMailAsync is a TAP wrapper around EAP methods, and that SignalR does not allow that.
My question is, is there any simple way to asynchronously send the emails directly from a hub method?
Or is my only option to place the email sending code elsewhere? (e.g. have the hub queue a service-bus message, then a stand-alone service could handle those messages and send the emails [though I'd also have more work this way to implement notification of results back to the hub's clients]; or have the hub make an HTTP request to a webservice that does the email sending).