C# ASP.NET标识发送电子邮件:TaskCanceledException
我正在尝试在asp.net identity 2.0应用程序中发送验证电子邮件地址电子邮件,但收到TaskCanceledException错误 我尝试了这条线中的内容: 如果我使用C# ASP.NET标识发送电子邮件:TaskCanceledException,c#,asp.net,.net,asp.net-identity,smtpclient,C#,Asp.net,.net,Asp.net Identity,Smtpclient,我正在尝试在asp.net identity 2.0应用程序中发送验证电子邮件地址电子邮件,但收到TaskCanceledException错误 我尝试了这条线中的内容: 如果我使用wait应用程序将永远运行:没有错误消息。但是第二个选项返回错误 错误被抛出:returnsmtpClient.SendMailAsync(msg) IdentityConfig.cs public async Task SendAsync(IdentityMessage message) {
wait
应用程序将永远运行:没有错误消息。但是第二个选项返回错误
错误被抛出:returnsmtpClient.SendMailAsync(msg)代码>
IdentityConfig.cs
public async Task SendAsync(IdentityMessage message)
{
// Plug in your email service here to send an email.
try
{
#region formatter
string text = string.Format("Please click on this link to {0}: {1}", message.Subject, message.Body);
string html = "Please confirm your account by clicking this link: <a href=\"" + message.Body + "\">link</a><br/>";
html += HttpUtility.HtmlEncode(@"Or click on the copy the following link on the browser:" + message.Body);
#endregion
MailMessage msg = new MailMessage();
msg.From = new MailAddress("");
msg.To.Add(new MailAddress(message.Destination));
msg.Subject = message.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));
using (var smtpClient = new SmtpClient())
{
smtpClient.EnableSsl = true;
smtpClient.SendCompleted += (s, e) => { smtpClient.Dispose(); };
await smtpClient.SendMailAsync(msg);
}
}
catch (Exception ex)
{
throw ex;
}
}
public async Task sendaync(IdentityMessage消息)
{
//在此处插入电子邮件服务以发送电子邮件。
尝试
{
#区域格式化程序
string text=string.Format(“请单击指向{0}:{1}”、message.Subject、message.Body的链接);
string html=“请单击此链接确认您的帐户:
”;
html+=HttpUtility.HtmlEncode(@)或单击复制浏览器上的以下链接:“+message.Body”;
#端区
MailMessage msg=新的MailMessage();
msg.From=新邮件地址(“”);
msg.To.Add(新邮件地址(message.Destination));
msg.Subject=message.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text,null,MediaTypeNames.text.Plain));
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html,null,MediaTypeNames.Text.html));
使用(var smtpClient=new smtpClient())
{
smtpClient.EnableSsl=true;
smtpClient.SendCompleted+=(s,e)=>{smtpClient.Dispose();};
等待smtpClient.SendMailAsync(msg);
}
}
捕获(例外情况除外)
{
掷骰子;
}
}
Register.aspx.cs
protected void CreateUser_Click(object sender, EventArgs e)
{
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = new ApplicationUser()
{
UserName = Email.Text,
Email = Email.Text,
UserProfileInfo = new UserProfileInfo
{
FirstName = Firstname.Text,
LastName = Lastname.Text,
Adress = Adress.Text,
Zip = Zip.Text,
City = City.Text,
Mobile = Mobile.Text
}
};
IdentityResult result = manager.Create(user, Password.Text);
if (result.Succeeded)
{
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
string code = manager.GenerateEmailConfirmationToken(user.Id);
string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");
manager.AddToRole(user.Id, "Konsument");
IdentityHelper.SignIn(manager, user, isPersistent: false);
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
}
else
{
ErrorMessage.Text = result.Errors.FirstOrDefault();
}
}
protectedvoid CreateUser\u单击(对象发送方,事件参数e)
{
var manager=Context.GetOwinContext().GetUserManager.);
manager.AddToRole(user.Id,“Konsument”);
IdentityHelper.SignIn(经理、用户、isPersistent:false);
IdentityHelper.RedirectToReturnUrl(Request.QueryString[“ReturnUrl”],响应);
}
其他的
{
ErrorMessage.Text=result.Errors.FirstOrDefault();
}
}
问题可能在于,在执行SendMailAsync时,smpt客户端已被释放。这就是引发异常的原因,但由于此操作在单独的线程(异步)中运行,因此会得到TaskCanceledException
您可以尝试删除using语句
public Task SendAsync(IdentityMessage message)
{
// Plug in your email service here to send an email.
try
{
#region formatter
string text = string.Format("Please click on this link to {0}: {1}", message.Subject, message.Body);
string html = "Please confirm your account by clicking this link: <a href=\"" + message.Body + "\">link</a><br/>";
html += HttpUtility.HtmlEncode(@"Or click on the copy the following link on the browser:" + message.Body);
#endregion
MailMessage msg = new MailMessage();
msg.From = new MailAddress("info@emailadress.com");
msg.To.Add(new MailAddress(message.Destination));
msg.Subject = message.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));
var smtpClient = new SmtpClient();
smtpClient.EnableSsl = true;
smtpClient.SendCompleted += (s, e) => { smtpClient.Dispose(); };
return smtpClient.SendMailAsync(msg);
}
catch (Exception)
{
return Task.FromResult(0);
}
}
public Task SendAsync(IdentityMessage消息)
{
//在此处插入电子邮件服务以发送电子邮件。
尝试
{
#区域格式化程序
string text=string.Format(“请单击指向{0}:{1}”、message.Subject、message.Body的链接);
string html=“请单击此链接确认您的帐户:
”;
html+=HttpUtility.HtmlEncode(@)或单击复制浏览器上的以下链接:“+message.Body”;
#端区
MailMessage msg=新的MailMessage();
msg.From=新邮件地址(“info@emailadress.com");
msg.To.Add(新邮件地址(message.Destination));
msg.Subject=message.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text,null,MediaTypeNames.text.Plain));
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html,null,MediaTypeNames.Text.html));
var smtpClient=新的smtpClient();
smtpClient.EnableSsl=true;
smtpClient.SendCompleted+=(s,e)=>{smtpClient.Dispose();};
返回smtpClient.SendMailAsync(msg);
}
捕获(例外)
{
返回Task.FromResult(0);
}
}
Smtp客户端将在SendCompleted处理程序的帮助下进行处理。@ntl正确识别了问题:请求完成之前正在处理SmtpClient
实例。但是,我更喜欢使用async
和Wait
作为解决方案:
public async Task SendAsync(IdentityMessage message)
{
...
using (var smtpClient = new SmtpClient())
{
smtpClient.EnableSsl = true;
smtpClient.SendCompleted += (s, e) => { smtpClient.Dispose(); };
await smtpClient.SendMailAsync(msg);
}
}
那么,让我们来解决最初的问题:
如果我使用wait,应用程序将永远运行:没有错误消息
我感觉到您的代码可能正在调用Task.Wait
或Task.Result
调用SendAsync
。这才是真正的问题:调用代码应该更改为使用Wait
(这使得调用方法异步
并返回任务
/任务
,这使得其调用代码必须使用等待
,等等)。允许异步
通过代码库自然“成长”。这就是为什么我的异步
最佳实践之一是“始终异步”
造成死锁的原因是,当您等待任务时,默认情况下,wait
将捕获“当前上下文”(在本例中,是ASP.NETSynchronizationContext
),并使用该上下文恢复async
方法。但是,ASP.NETSynchronizationContext
一次只允许每个请求有一个线程,因此当调用代码阻塞时(通过调用Wait
或Result
),它在该上下文中阻塞了一个线程,async
方法无法恢复
最好的解决方案是使用等待
,并一直使用异步
。像永远一样等待本地主机。如果我得到你的答案,我喜欢它,它的简单的.MailMessage也应该被释放…也许你只是想保持同步…仍然只是运行而已forever@MaddePersson:请提供一个最小的代码示例产生问题。我更新了我的代码,并包含register.aspx.cs代码。@MaddePersson:您的代码不调用SendAsync
。您需要做的是1)复制现有的解决方案。2)在保持死锁的同时尽可能删除所有代码。3)发布所有剩余的代码。不要撤消