gpt4 book ai didi

c# - 从异步方法调用同步方法

转载 作者:太空狗 更新时间:2023-10-30 00:23:08 24 4
gpt4 key购买 nike

我正在为 ASP.NET Identity 实现 EmailServer

我不喜欢 async...awaitusing 不兼容,所以我的电子邮件方法是同步的。

那么如何从框架的 SendAsync 方法中调用它呢?

public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
Email email = new Email();
return Task.FromResult<void>(email.Send(message));
}
}

在上面的代码中,Task.FromResult() 给我一个错误,指出 void 不能用作参数类型。但是 email.Send() 返回无效!

如何走出这个泥潭?

最佳答案

如果您没有结果,则不要尝试返回结果。只需返回一个普通的,完成的Task :

public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
new Email().Send(message);
return Task.CompletedTask;
}
}

如果您卡在 4.6 之前的土地上,那么您可以使用 Task.FromResult<bool>(true)相反。

总而言之,我对您关于async...awaitusing 不兼容”的评论感到困惑。根据我的经验,这很好用。如果您的方法实际上是异步的,那就更好了。我认为通过关注如何做到这一点,而不是伪造 async 的最佳/正确语法,你会得到更好的服务。方法。

附录:

我仍然不清楚您对使用 using 的担忧.但是,根据您的评论,您似乎想使用 SmtpClient.SendAsync()但不确定如何在 async 的上下文中应用它/await .

不幸的是,甚至在 async 之前/await ,我们在 .NET 中有很多异步方法,这些方法使用与新可等待方法约定相同的命名。 (需要明确的是:不幸的是命名,而不是异步方法的存在:))。但是,在所有情况下,都可以使旧 API 适应新 API。

在某些情况下,它就像使用 Task.FromAsync() 一样简单方法。这适用于任何支持旧 Begin... 的东西/End...模型。但是 SmtpClient.SendAsync() model 是一种基于事件的回调方法,需要稍微不同的方法。

注意:我在编写下面的示例后注意到 SmtpClient类有一个 Task基于异步操作的方法, SendMailAsync() .所以实际上,没有必要适应旧的 SendAsync()方法。但这是一个有用的例子,可以展示当 Task 时如何进行这种调整。尚未提供基于 -based 的替代方案。

简而言之,您可以使用 TaskCompletionSourceSendCompleted SmtpClient 上的事件目的。这是一个大概的样子:

public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
// I'm not familiar with "IdentityMessage". Let's assume for the sake
// of this example that you can somehow adapt it to the "MailMessage"
// type required by the "SmtpClient" object. That's a whole other question.
// Here, "IdentityToMailMessage" is some hypothetical method you write
// to handle that. I have no idea what goes inside that. :)
using (MailMessage mailMessage = IdentityToMailMessage(message))
using (SmtpClient smtpClient = new SmtpClient())
{
TaskCompletionSource<bool> taskSource = new TaskCompletionSource<bool>();

// Configure "smtpClient" as needed, such as provided host information.
// Not shown here!

smtpClient.SendCompleted += (sender, e) => taskSource.SetResult(true);
smtpClient.SendAsync(mailMessage, null);

await taskSource.Task;
}
}
}

上面将启动异步操作,并使用SendCompleted事件的处理程序(即文档所指的“回调”)为 TaskCompletionSource<bool> 设置结果对象(结果值从未真正使用过,但没有 TaskTaskCompletionSource 版本……你必须有 一些 值)。

它使用 await ,而不是返回 taskSource.Task直接对象,因为这样它可以正确处理处理 SmtpClient当电子邮件操作实际上已完成时反对。

关于c# - 从异步方法调用同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43624083/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com