SB2*_*055 4 .net c# asynchronous task-parallel-library async-await
我有一个按钮——当用户点击它时——会发送一封电子邮件。我希望它立即返回并在后台发送电子邮件,而无需在处理电子邮件时阻止 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))
}
笔记:
Task没有awaiting 的情况下启动它,除非您处于无法使用的情况await(UI 事件处理程序不是这些情况之一)async void仅适用于 UI 事件处理程序。不要在其他任何地方使用它。您可以在任务中运行您的方法而不等待它:
private void button_Click(object sender, EventArgs e)
{
   Task.Run( () => SendEMail(address, subject, body) );
}
| 归档时间: | 
 | 
| 查看次数: | 5874 次 | 
| 最近记录: |