c# - 从 SignalR 集线器发送异步邮件

标签 c# email signalr async-await smtpclient

作为 SignalR 中心调用的结果,我需要发送电子邮件。我不希望发送同步执行,因为我不想绑定(bind) WebSocket 连接,但如果可能的话,我希望在出现任何错误时通知调用者。我认为我可以在集线器中使用类似的东西(减去错误处理和我希望它做的所有其他事情):

public class MyHub : Hub {
    public async Task DoSomething() {
        var client = new SmtpClient();
        var message = new MailMessage(/* setup message here */);
        await client.SendMailAsync(message);
    }
}

但是很快发现不行; client.SendMailAsync 调用抛出这个:

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.

进一步的调查和阅读表明 SmtpClient.SendMailAsync 是围绕 EAP 方法的 TAP 包装器,而 SignalR 不允许这样做。

我的问题是,是否有任何简单的方法可以直接从 hub 方法异步发送电子邮件?

或者我唯一的选择是将电子邮件发送代码放在别处吗? (例如,让集线器排队服务总线消息,然后独立服务可以处理这些消息并发送电子邮件[尽管我也有更多的工作通过这种方式将结果通知回集线器的客户端];或让集线器向执行电子邮件发送的网络服务发出 HTTP 请求。

最佳答案

类似问题herehere .

SignalR 团队是 aware of the issue ,但还没有修好。此时它看起来会进入 SignalR v3。

与此同时,一个快速的 hack 是这样的:

public async Task DoSomething() {
  using (new IgnoreSynchronizationContext())
  {
    var client = new SmtpClient();
    var message = new MailMessage(/* setup message here */);
    await client.SendMailAsync(message);
  }
}

public sealed class IgnoreSynchronizationContext : IDisposable
{
  private readonly SynchronizationContext _original;
  public IgnoreSynchronizationContext()
  {
    _original = SynchronizationContext.Current;
    SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
  }
  public void Dispose()
  {
    SynchronizationContext.SetSynchronizationContext(_original);
  }
}

关于c# - 从 SignalR 集线器发送异步邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24377081/

相关文章:

asp.net - SignalR 和负载平衡与主动/主动粘性 session

c# - 类型或命名空间名称不存在

c# - MVVM跟踪 View 模型中的问题

php - 忘记密码。在 yahoo/gmail 或其他邮件中收不到电子邮件

networking - 网络代理或加速器的 SignalR 问题?

ninject - SignalR 依赖解析器无法在 Javascript 中心工作

c# - Visual Studio,同步命名空间,特定文件除外

c# - 如何将原始数据显示为图像 (Visual Studio c#)

python - 尝试使用 ExchangeLib 返回过去 24 小时内的电子邮件

mysql - 当行插入表时如何通过邮件收到通知?