Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET标识发送电子邮件:TaskCanceledException_C#_Asp.net_.net_Asp.net Identity_Smtpclient - Fatal编程技术网

C# ASP.NET标识发送电子邮件: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) {

我正在尝试在asp.net identity 2.0应用程序中发送验证电子邮件地址电子邮件,但收到TaskCanceledException错误

我尝试了这条线中的内容:

如果我使用
wait
应用程序将永远运行:没有错误消息。但是第二个选项返回错误

错误被抛出:return
smtpClient.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.NET
SynchronizationContext
),并使用该上下文恢复
async
方法。但是,ASP.NET
SynchronizationContext
一次只允许每个请求有一个线程,因此当调用代码阻塞时(通过调用
Wait
Result
),它在该上下文中阻塞了一个线程,
async
方法无法恢复


最好的解决方案是使用
等待
,并一直使用
异步

像永远一样等待本地主机。如果我得到你的答案,我喜欢它,它的简单的.MailMessage也应该被释放…也许你只是想保持同步…仍然只是运行而已forever@MaddePersson:请提供一个最小的代码示例产生问题。我更新了我的代码,并包含register.aspx.cs代码。@MaddePersson:您的代码不调用
SendAsync
。您需要做的是1)复制现有的解决方案。2)在保持死锁的同时尽可能删除所有代码。3)发布所有剩余的代码。不要撤消