【问题标题】:Why isn't SmtpClient.SendAsync async?为什么 SmtpClient.SendAsync 不是异步的?
【发布时间】:2018-05-19 02:07:22
【问题描述】:

参考:https://github.com/dotnet/corefx/blob/master/src/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs#L583

此方法被标记为异步但返回 void。它实际上是异步的并且不是基于任务的吗?如果是这样,它是如何异步的?

【问题讨论】:

  • 因为它会在 TBA 成为运行时的一部分之前构思和实施
  • 不包括反对票,尽管我确实犯了一个明显的错字
  • 不确定他们为什么选择 async void,但这里的这篇文章很好地解释了 async void:stackoverflow.com/questions/41685636/…
  • 你当然可以使用client.SendMailAsync() :)
  • @mariocatch SendAsync 不是async void;它是一个pre-async/await,基于事件的异步方法。 OTOH,SendMailAsync 适当地返回 Task,因为它是围绕 TPL 设计的

标签: c# asynchronous async-await task task-parallel-library


【解决方案1】:

在官方docs 页面上有一些关于您对此方法的特定问题的信息。

要在电子邮件已发送或操作已取消时接收通知,请将事件处理程序添加到 SendCompleted 事件。

这意味着方法没有阻塞,但不能等待,因为它对 TPL 一无所知。您应该订阅 SendCompleted 事件。 通过我提供的链接检查代码示例以查看可能的使用场景。

虽然SendMailAsync 是使用基于任务的异步模式实现的,但可能应该使用它。

【讨论】:

    【解决方案2】:

    如果您阅读了该代码,您可能忽略了 AsyncOpManager - 请参阅 https://github.com/dotnet/corefx/blob/master/src/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs#L662 :)

    然而,事实上,在下面的switch 中,我们看到了:

    • SmtpDeliveryMethod.PickupDirectoryFromIis:总是抛出
    • SmtpDeliveryMethod.SpecifiedPickupDirectory:似乎 100% 同步(直接调用 message.Send(_writer, true, allowUnicode)writer.Close_transport.ReleaseConnection
    • SmtpDeliveryMethod.Network/default:似乎 100% 异步(_transport.BeginGetConnection 开始操作,我没有看到任何等待或继续)

    (至少如果我读好代码,我并没有深入那里)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-21
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多