如果没有结果,那就不要试图返回一个结果。只需返回一个简单、已完成的
Task
:
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
new Email().Send(message);
return Task.CompletedTask;
}
}
如果您仍然停留在4.6之前的版本,则可以使用
Task.FromResult<bool>(true)
代替。
话虽如此,我对您关于"
async...await
与
using
不兼容"的评论感到困惑。根据我的经验,这是有效的。如果您的方法实际上是异步的,那将会更好。我认为您最好专注于如何做到这一点,而不是伪造
async
方法的最佳/正确语法。
补充:
我仍然不清楚您对使用
using
的担忧。但是,根据您的评论,似乎您想使用
SmtpClient.SendAsync()
,但不确定如何在
async
/
await
的上下文中应用它。
不幸的是,在
async
/
await
之前,.NET中有许多异步方法,并且这些方法使用了与新可等待方法约定相同的命名。 (要明确:不幸的是命名方式,而不是异步方法存在:))。但是,在所有情况下,都可以将旧API适应新API。
在某些情况下,只需使用
Task.FromAsync()
方法即可。这适用于支持旧的
Begin...
/
End...
模型的任何内容。但是,
SmtpClient.SendAsync()
模型是基于事件回调的方法,需要稍微不同的方法。
注意:在编写下面示例之后,我注意到
SmtpClient
类具有基于
Task
的异步操作方法
SendMailAsync()
。因此,实际上没有必要适应旧的
SendAsync()
方法。但是,这是一个有用的示例,可以展示如何在未提供基于
Task
的替代方案时进行适应。简而言之,您可以使用
TaskCompletionSource
和
SmtpClient
对象上的
SendCompleted
事件。以下是大致的外观:
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
using (MailMessage mailMessage = IdentityToMailMessage(message))
using (SmtpClient smtpClient = new SmtpClient())
{
TaskCompletionSource<bool> taskSource = new TaskCompletionSource<bool>();
smtpClient.SendCompleted += (sender, e) => taskSource.SetResult(true);
smtpClient.SendAsync(mailMessage, null);
await taskSource.Task;
}
}
}
上述代码将启动异步操作,并使用 SendCompleted 事件处理程序(即文档所指的“回调”)来设置 TaskCompletionSource 对象的结果(结果值实际上从未被使用,但没有纯粹的 Task 版本的 TaskCompletionSource…必须有一些值)。
它使用 await 而不是直接返回 taskSource.Task 对象,因为这样可以在电子邮件操作实际完成时正确处理 SmtpClient 对象的释放。
using
和async
关键字有什么不喜欢的地方(例如在https://dev59.com/L2Qn5IYBdhLWcg3wzZtU中展示的)? - Alexei LevenkovSmtpClient.SendAsync()
需要一个第二个参数,似乎与回调有关。这就是我想避免的。 - Jonathan Wood