天天看點

詳解Asp.Net定時發送郵件方法

用.net發送郵件,總結起來有以下那麼三種:

(1)做一個winform 來定時發郵件。然後通過windows計劃任務,設定為指定時間,每次自動運作,運作完畢後自動關閉。

(2)用sqlserver 資料庫實作發郵件,用sqlserver實作發郵件的存儲過程,然後制定一個作業,制定時間運作。

(3)在 Global.asax 檔案裡程式設計。事件:Application_Start。利用Time類程式設計。比如伺服器1秒鐘執行一次判斷。

在程式設計之前,先介紹一下 Global.asax檔案裡的幾個方法。

  protected void Application_Start(Object sender, EventArgs e)

  {

  //Application_start方法:請求 ASP.NET 應用程式中第一個資源(如頁)時調用。在應用程式的生命周期期間僅調用一次

  }

  protected void Application_End(Object sender, EventArgs e)

  {

  //Application_end方法:在解除安裝應用程式之前對每個應用程式生命周期調用一次。

  }

下面是具體的做法:

  代碼

  protected void Application_Start(Object sender, EventArgs e)

  {

  Timer t = new Timer(60000);//設計時間間隔,如果一個小時執行一次就改為3600000 ,這裡一分鐘調用一次

  t.Elapsed  = new ElapsedEventHandler(t_Elapsed);

  t.AutoReset = true;

  t.Enabled = true;

  }

  private void t_Elapsed(object sender, ElapsedEventArgs e)

  {

  if (GetEmailContent.GetMailContent().Length == 0)

  {

  return;//如果沒有通過三審的訂單要發送,則傳回不發送郵件

  }

歡迎進入.NET社群論壇,與200萬技術人員互動交流 >>進入

  int sendTime_Hour = Convert.ToInt32(ConfigurationManager.AppSettings["SendTime"].ToString());// 假如是下午17:00分發送

  int now_Hour = Convert.ToInt32(DateTime.Now.Hour.ToString());

  int now_Minute = Convert.ToInt32(DateTime.Now.Minute.ToString());

  int absolute = 1;//差距值,機關為分鐘

  if (((now_Hour == sendTime_Hour - 1) && (now_Minute >= 60 - absolute)) || ((now_Hour == sendTime_Hour) && (now_Minute <= absolute)))    //即在如果時間判斷是落在16:59分至17:01分之間,那麼就會調用下面的郵件發送方法

  {

  string subject = string.Format("CO Approve Report({0})", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

  string host = ConfigurationManager.AppSettings["MailHost"];

  string from = ConfigurationManager.AppSettings["MailFrom"];

  string to = ConfigurationManager.AppSettings["MailTo"];

  string user = ConfigurationManager.AppSettings["MailUser"];

  string password = ConfigurationManager.AppSettings["MailPassword"];

  string content = GetEmailContent.GetMailContent();

  try

  {

  OrderMail.Send(host, user, password, to, from, subject, content, null);//發送郵件的方法,改為你自己的郵件發送方法

  }

  catch (Exception ex)

  {

  throw new Exception(ex.Message);

  }

  }

  }

  如果一定要确精到分,可以設定相距時間為秒級,以及設定定時器的時間間隔為秒級,比如一秒調用一次t_Elapsed,但必須符合的一件條件是:定時器的時間間隔<2*absolute,absolute為差距值,見上面黃色背景的定義,具體多少以客戶的要求為準,不滿足這個條件的話不能實作在規定的時間段内調用郵件發送的方法。

  好,代碼編寫完畢,測試沒問題,下班再設定晚上9點收到郵件(理論值應是8點59至9點1分之間收到),當天發現沒收到郵件,問題來了!為什麼在上班的測試沒問題,但下班後9點沒收到郵件?網上查了一下,發覺自己還有個問題沒考慮到:Application對象是有生命周期的,當網頁沒人通路或閑置過久,應用程式池會調用Application_End方法回收applicatioin裡的對象資源,導緻定時器無法工作。

  解決方法:在IIS6.0以上版本設定IIS應用程式池的回收時間,預設好像是20分鐘,可設定長一些,但不要太長,否則有可能出現網站假死的現象。當晚再測試,可以正式發送郵件!起碼到現在已經用了兩三個月,都能正常定時發送郵件。IIS5.0沒有應用程式池,可以在C:WINDOWS Microsoft.NETFrameworkv2.0.50727CONFIG machine.config裡面設定,具體設定可以參照:http://www.zhiweinet.com/jiaocheng/2008-07 /1145.htm

  還有,對于Applicatioin_Start方法,有很多人都會産生一個誤解: Application_Start是第一個人通路網站時加載的,隻會調用一次,以後都不會調用;Application_Start是第一個人通路網站時加載的,這個沒錯,前提是在它的生命周期内,有以下幾個原因也會導緻應用程式池重新啟動,  即Application_Start可以再次被調用:

  1)添加、修改或删除應用程式的 Bin 檔案夾中的程式集。

  2)添加、修改或删除 App_GlobalResources 或 App_LocalResources 檔案夾中的本地化資源。

  3)添加、修改或删除應用程式的 Global.asax 檔案。

  4)添加、修改或删除 App_Code 目錄中的源代碼檔案。

  5)添加、修改或删除配置檔案配置。

  6)添加、修改或删除 App_WebReferences 目錄中的 Web 服務引用。

  7)添加、修改或删除應用程式的 Web.config 檔案。

  附應用程式生命周期概述:http://www.cnblogs.com/adsiz/archive/2008/01/17 /1042746.html

  附.NET垃圾回收機制 :http://blog.csdn.net/lerit/archive/2009/08/16/4451287.aspx

  附SqlServer發送郵件解決方法:http://www.cnblogs.com/yjmyzz/archive/2008/09/04 /1284229.html

  在正常情況下Application_Start隻調用一次,這樣就不會執行個體化無數個定時器而占用伺服器的資源 ,還有個問題是定時器的時間間隔如果精确到秒級的話是否會占用很多的記憶體,吃記憶體是肯定會的,是以要根據具體的情況設定應用程式池的回收時間和加大定時器設定的時間間隔。

  上面定時發送郵件的解決方法隻是我個人的做法,可供參考,不見得是最好的方法。QQ郵箱與163郵箱都可以實作發送郵件的功能,大家可否讨論下他們是怎樣實作的。

繼續閱讀