2011-03-09 52 views
3

我有用C#編寫的用於發送電子郵件的代碼,但應用程序發送的郵件大小超過2 MB時,應用程序將掛起。建議SO用戶使用後臺工作進程。需要使用後臺工作進程發送電子郵件

我已經通過MSDN的後臺工作進程示例和谷歌它也,但我不知道如何集成在我的代碼。

請指引我在...

感謝

更新:電子郵件碼添加

public static void SendMail(string fromAddress, string[] toAddress, string[] ccAddress, string[] bccAddress, string subject, string messageBody, bool isBodyHtml, ArrayList attachments, string host, string username, string pwd, string port) 
{ 
    Int32 TimeoutValue = 0; 
    Int32 FileAttachmentLength = 0; 
    { 
    try 
    { 
     if (isBodyHtml && !htmlTaxExpression.IsMatch(messageBody)) 
     isBodyHtml = false; 
     // Create the mail message 
     MailMessage objMailMsg; 
     objMailMsg = new MailMessage(); 
     if (toAddress != null) { 
     foreach (string toAddr in toAddress) 
      objMailMsg.To.Add(new MailAddress(toAddr)); 
     } 
     if (ccAddress != null) { 
     foreach (string ccAddr in ccAddress) 
      objMailMsg.CC.Add(new MailAddress(ccAddr)); 
     } 
     if (bccAddress != null) { 
     foreach (string bccAddr in bccAddress) 
      objMailMsg.Bcc.Add(new MailAddress(bccAddr)); 
     } 
     if (fromAddress != null && fromAddress.Trim().Length > 0) { 
     //if (fromAddress != null && fromName.trim().length > 0) 
     // objMailMsg.From = new MailAddress(fromAddress, fromName); 
     //else 
     objMailMsg.From = new MailAddress(fromAddress); 
     } 
     objMailMsg.BodyEncoding = Encoding.UTF8; 
     objMailMsg.Subject = subject; 
     objMailMsg.Body = messageBody; 
     objMailMsg.IsBodyHtml = isBodyHtml; 
     if (attachments != null) { 
     foreach (string fileName in attachments) { 
      if (fileName.Trim().Length > 0 && File.Exists(fileName)) { 
      Attachment objAttachment = new Attachment(fileName); 
      FileAttachmentLength=Convert.ToInt32(objAttachment.ContentStream.Length); 
      if (FileAttachmentLength >= 2097152) { 
       TimeoutValue = 900000; 
      } else { 
       TimeoutValue = 300000; 
      } 
      objMailMsg.Attachments.Add(objAttachment); 
      //objMailMsg.Attachments.Add(new Attachment(fileName)); 
      } 
     } 
     } 
     //prepare to send mail via SMTP transport 
     SmtpClient objSMTPClient = new SmtpClient(); 
     if (objSMTPClient.Credentials != null) { } else { 
     objSMTPClient.UseDefaultCredentials = false; 
     NetworkCredential SMTPUserInfo = new NetworkCredential(username, pwd); 
     objSMTPClient.Host = host; 
     objSMTPClient.Port = Int16.Parse(port); 
     //objSMTPClient.UseDefaultCredentials = false; 
     objSMTPClient.Credentials = SMTPUserInfo; 
     //objSMTPClient.EnableSsl = true; 
     //objSMTPClient.DeliveryMethod = SmtpDeliveryMethod.Network; 
     } 
     //objSMTPClient.Host = stmpservername; 
     //objSMTPClient.Credentials 
     //System.Net.Configuration.MailSettingsSectionGroup mMailsettings = null; 
     //string mailHost = mMailsettings.Smtp.Network.Host; 
     try { 
     objSMTPClient.Timeout = TimeoutValue; 
     objSMTPClient.Send(objMailMsg); 
     //objSMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); 
     objMailMsg.Dispose(); 
     } 
     catch (SmtpException smtpEx) { 
     if (smtpEx.Message.Contains("secure connection")) { 
      objSMTPClient.EnableSsl = true; 
      objSMTPClient.Send(objMailMsg); 
     } 
     } 
    } 
    catch (Exception ex) 
    { 
     AppError objError = new AppError(AppErrorType.ERR_SENDING_MAIL, null, null, new AppSession(), ex); 
     objError.PostError(); 
     throw ex; 
    } 
    } 
} 

我不能在這裏修改代碼,因爲它是常見的方法被稱爲每當我的應用程序發送郵件。

+0

如果您可以提供您當前的代碼將是有幫助的。我們可以將它轉換爲背景,而不是我們提供的例子,您可能不知道如何適合您的代碼。 – 2011-03-09 06:54:49

+0

@Fun Mun Pieng:我添加了代碼.. – 2011-03-09 07:19:58

+0

我修改了我的答案。 – 2011-03-09 07:29:20

回答

6

你可以啓動一個後臺線程,不斷循環和發送電子郵件:

private void buttonStart_Click(object sender, EventArgs e) 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    this.Controls.Add(bw); 
    bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
    bw.RunWorkerAsync(); 
} 

private bool quit = false; 
void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (!quit) 
    { 
     // Code to send email here 
    } 
} 

替代的方式來做到這一點:

private void buttonStart_Click(object sender, EventArgs e) 
{ 
    System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(); 
    client.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(client_SendCompleted); 
    client.SendAsync("[email protected]", "[email protected]", "subject", "body", null); 
} 

void client_SendCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    if (e.Error == null) 
     MessageBox.Show("Successful"); 
    else 
     MessageBox.Show("Error: " + e.Error.ToString()); 
} 

具體到你的榜樣,你應該替換以下:

try 
{ 
    objSMTPClient.Timeout = TimeoutValue; 
    objSMTPClient.Send(objMailMsg); 
    //objSMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); 
    objMailMsg.Dispose(); 
} 
catch (SmtpException smtpEx) 
{ 
    if (smtpEx.Message.Contains("secure connection")) 
    { 
     objSMTPClient.EnableSsl = true; 
     objSMTPClient.Send(objMailMsg); 
    } 
} 

有以下幾點:

objSMTPClient.Timeout = TimeoutValue; 
objSMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); 
objSMTPClient.SendAsync(objMailMsg, objSMTPClient); 

進一步回落,包括:

void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) 
{ 
    if (e.Error == null) 
     MessageBox.Show("Successful"); 
    else if (e.Error is SmtpException) 
    { 
     if ((e.Error as SmtpException).Message.Contains("secure connection")) 
     { 
      (e.UserState as SmtpClient).EnableSsl = true; 
      (e.UserState as SmtpClient).SendAsync(objMailMsg, e.UserState); 
     } 
     else 
      MessageBox.Show("Error: " + e.Error.ToString()); 
    } 
    else 
     MessageBox.Show("Error: " + e.Error.ToString()); 
} 
+0

感謝您的輸入。因此,此代碼不需要包含任何後臺進程? 另外我沒有在intellisense中獲得AsyncCompletedEventArgs。這可能是什麼原因? – 2011-03-09 07:32:17

+0

添加'使用System.ComponentModel;'或將其更改爲'System.ComponentModel.AsyncCompletedEventArgs' – 2011-03-09 07:34:02

+0

感謝您再次輸入。最後的評論工作! 但電子郵件沒有被髮送。不知道爲什麼.. – 2011-03-09 07:58:59

1

有如何做到這一點與「服務代理」理查德Kiessig的著作「超第8章的一個很好的例子快速ASP.NET「。

下面是出版商網站上書籍的鏈接,您可以從書中下載示例代碼。再次,第8章......

http://apress.com/book/view/9781430223832

+0

使用Service Broker發送電子郵件的優勢在於請求被保留,所以它們可以在AppPool重新啓動之後繼續存在,並且出於安全性和/或可擴展性的原因,可以根據需要將任務移至單獨的服務器。 – RickNZ 2011-12-02 04:17:29

相關問題