gpt4 book ai didi

c# - 在 C# 中使函数非阻塞/异步的简单方法?

转载 作者:行者123 更新时间:2023-11-30 13:56:26 27 4
gpt4 key购买 nike

我有一个按钮 - 当用户点击它时 - 发送一封电子邮件。我希望它能立即返回并在后台发送电子邮件,而无需在处理电子邮件时保留 UI。我四处搜索了 async/await/etc,我发现了很多不同的方法 - 我正在寻找一个简单的解决方案。我的电子邮件代码:

public void SendEmail(string toAddress, string subject, string body, string code = null) {
try {

var fromAddressObj = new MailAddress("noreply@me.com", "Name");
var toAddressObj = new MailAddress(toAddress, toAddress);
const string fromPassword = "Password";

var smtp = new SmtpClient {
Host = "smtp.office365.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddressObj.Address, fromPassword)
};
using (var message = new MailMessage(fromAddressObj, toAddressObj) {
Subject = subject,
IsBodyHtml = true

}) {
message.Body = body;
smtp.Send(message);
}

} catch (Exception e) {
Elmah.ErrorSignal.FromCurrentContext().Raise(e);
}
}

我怎样才能修改它,以便调用者不被阻止?

最佳答案

SmtpClient 具有 SendMailAsync,因此使用它代替 Send 将在发送时解锁 UI 线程,但您仍然可以处理可能发生的任何异常:

private async void button_Click(object sender, EventArgs e)
{
await SendEmailAsync(address, subject, body)
}

public async Task SendEmailAsync(string toAddress, string subject, string body, string code = null)
{
try
{
var fromAddressObj = new MailAddress("noreply@me.com", "Name");
var toAddressObj = new MailAddress(toAddress, toAddress);
const string fromPassword = "Password";

var smtp = new SmtpClient {
Host = "smtp.office365.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddressObj.Address, fromPassword)
};
using (var message = new MailMessage(fromAddressObj, toAddressObj)
{
Subject = subject,
IsBodyHtml = true
})
{
message.Body = body;
await smtp.SendMailAsync(message);
}
}
catch (Exception e)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(e);
}
}

如果 async 方法的同步部分(await 之前的部分)仍然设法阻塞 UI 线程,您可以将其卸载到 ThreadPool线程:

private async void button_Click(object sender, EventArgs e)
{
await Task.Run(() => SendEmailAsync(address, subject, body))
}

注意事项:

  • 不要在没有 await 的情况下启动 Task 除非您处于无法使用 await 的情况下( UI 事件处理程序不是其中一种情况)
  • async void 仅适用于 UI 事件处理程序。不要在其他任何地方使用它。

关于c# - 在 C# 中使函数非阻塞/异步的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28536092/

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