2015-09-10 25 views
1

您好,感謝您提前爲您出謀劃策,查找平行的ForEach線程拋出異常

我有一個並行for每個散發出大量電子郵件循環。我想知道的是如何找出哪個線程拋出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); 
    } 
} 
+0

你有沒有想過用'try-catch'封裝調用? –

+0

我正在使用Try-Catch? – JohnCoderMan

+0

如何:處理並行循環中的異常 (https://msdn.microsoft.com/en-us/library/Dd460695(v=VS.110).aspx) – MrDywar

回答

1

你可以按照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; 
+0

更好地使用ConcurrentQueue或另一個線程保存集合。 – MrDywar

+0

這將隱藏錯誤,我會拋出一個新的異常,包含在郵件中的電子郵件,並具有SMTP異常作爲內部異常,除非詛咒你可以處理它在捕獲使錯誤消失 – MikeT

+0

@MrDywar你可以在添加處理併發問題之前,還要添加'lock(errorList)'。 – jgg99

0

您可以配置Visual Studio調試器(我假設您正在使用)在拋出異常時斷開它。

打開調試菜單,單擊例外項目。使用查找按鈕搜索SmtpException,然後單擊「Thrown」列中的複選框。當你再次執行你的程序時,它會告訴你發生的確切時刻,以及調用堆棧,局部變量等。

+0

這不會幫助最終用戶確定電子郵件是否被髮送 – JohnCoderMan

+0

我的歉意,您的問題的措辭意味着您想調試問題,而不是通知最終用戶。 – jgg99