查找哪个 Parallel ForEach 线程抛出异常

Find which Parallel ForEach thread threw exception

您好,提前感谢您的建议,

我有一个并行的 For-each 循环,它正在发送大量电子邮件。我想知道的是如何找出哪个线程抛出了 SmtpException。我想知道它无法发送到哪个电子邮件地址。

protected void btnSend_Click(object sender, EventArgs e)
{
    try
    {
        if (Page.IsValid)
        {
            List<string> emailList;
            List<string> invalidList = new List<string> { };
            string[] attachments = { };
            if (rbListType.Items.FindByValue("CSV").Selected)
            {
                emailList = tbEmailTo.Text.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
                int count = 0;
                int total = emailList.Count;
                RadRadialGauge1.Scale.Max = total;
                RadRadialGauge1.Scale.Min = 0;
                //for (int i = 0; i < emailList.Count; i++)
                //{
                //    if (emailList[i].Contains('<'))
                //    {
                //        if (!Mail.IsValidEmailAddress(emailList[i].ToString().Split('<')[1].Replace(">", ""), PortalId))
                //        {
                //            emailList.RemoveAt(i);
                //            invalidList.Add(emailList[i].ToString());
                //        }
                //    }
                //    else
                //    {
                //        if (!Mail.IsValidEmailAddress(emailList[i].ToString(), PortalId))
                //        {
                //            emailList.RemoveAt(i);
                //            invalidList.Add(emailList[i].ToString());
                //        }
                //    }
                //}

                Parallel.ForEach(emailList, email =>
                {
                    Mail.SendMail(tbEmailFrom.Text, email.ToString(), tbEmailCC.Text, tbEmailBC.Text, tbReplyTo.Text, DotNetNuke.Services.Mail.MailPriority.Normal,
                        tbSubject.Text, MailFormat.Html, System.Text.Encoding.UTF8, tbEmailBody.Text, attachments, smtpServer, smtpAuthentication, smtpUsername, smtpPassword, false);
                    Interlocked.Increment(ref count);

                });

                RadRadialGauge1.Pointer.Value = count;

            }
            if (rbListType.Items.FindByValue("Excel").Selected)
            {
                emailList = tbEmailTo.Text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                int count = 0;
                int total = emailList.Count;
                RadRadialGauge1.Scale.Max = total;
                RadRadialGauge1.Scale.Min = 0;
                //for (int i = 0; i < emailList.Count; i++)
                //{
                //    if (emailList[i].Contains('<'))
                //    {
                //        if (!Mail.IsValidEmailAddress(emailList[i].ToString().Split('<')[1].Replace(">", ""), PortalId))
                //        {
                //            emailList.RemoveAt(i);
                //            invalidList.Add(emailList[i].ToString());
                //        }
                //    }
                //    else
                //    {
                //        if (!Mail.IsValidEmailAddress(emailList[i].ToString(), PortalId))
                //        {
                //            emailList.RemoveAt(i);
                //            invalidList.Add(emailList[i].ToString());
                //        }
                //    }
                //}


                Parallel.ForEach(emailList, email =>
                {

                    Mail.SendMail(tbEmailFrom.Text, email.ToString(), tbEmailCC.Text, tbEmailBC.Text, tbReplyTo.Text, DotNetNuke.Services.Mail.MailPriority.Normal,
                       tbSubject.Text, MailFormat.Html, System.Text.Encoding.UTF8, tbEmailBody.Text, attachments, smtpServer, smtpAuthentication, smtpUsername, smtpPassword, false);
                    Interlocked.Increment(ref count);

                });
                RadRadialGauge1.Pointer.Value = count;
            }

            throw new SmtpException();
        }
    }
    catch (SmtpException smtp)
    {
        RadRadialGauge1.Pointer.Value = RadRadialGauge1.Pointer.Value - 1;
        var email = smtp.

        Exceptions.LogException(smtp);

    }
    catch (Exception ex)
    {
        Exceptions.LogException(ex);
    }
}

您可以将 Visual Studio 调试器(我假设您正在使用)配置为在抛出异常时立即中断。

打开“调试”菜单,单击“异常”项。使用查找按钮,搜索 SmtpException,然后单击 "Thrown" 列中的复选框。当你再次执行你的程序时,它会显示它发生的确切时刻,以及调用堆栈、局部变量等。

您可以按照 Yuval Itzchakov 的建议将其包装在 try catch 中。然后在最后 errorList 将填充所有无法发送的电子邮件地址。

var errorList = new ConcurrentBag<string>();
Parallel.ForEach(emailList, email =>
{
     try
     {
         Mail.SendMail(tbEmailFrom.Text, email.ToString(), tbEmailCC.Text, tbEmailBC.Text, tbReplyTo.Text, DotNetNuke.Services.Mail.MailPriority.Normal,
         tbSubject.Text, MailFormat.Html, System.Text.Encoding.UTF8, tbEmailBody.Text, attachments, smtpServer, smtpAuthentication, smtpUsername, smtpPassword, false);
         Interlocked.Increment(ref count);  
     }
     catch(SmtpException stmp)
     {
         Exceptions.LogException(smtp);
         errorList.Add(email);
     }   
});
RadRadialGauge1.Pointer.Value = count;