asp.net定時發送郵件總結

來源:互聯網
上載者:User

       香港那邊公司的市場部開會時要求我們這邊實現一個定時發送郵件的功能,即在每天下午5點左右定時把今天已通過三審的訂單資訊發給市場部的經理,告訴他哪些訂單已經通過了終審。平時只知道如何用.net發送郵件,但不知如何定時發送郵件。於是百度了一下,總結起來有以下那麼三種:

(1)做一個winform 來定時發郵件。然後通過windows計劃任務,設定為指定時間,每次自動運行,運行完畢後自動關閉。
(2)用sqlserver 資料庫實現發郵件,用sqlserver實現發郵件的預存程序,然後制定一個作業,制定時間運行。
(3)在 Global.asax 檔案裡編程。事件:Application_Start。利用Time類編程。比如伺服器1秒鐘執行一次判斷。

          香港那邊的公司的ERP糸統是BS模式,由於對方公司伺服器環境條件與解決方案要簡單的限制,我和我師傅決定用第三種方法。在編程之前,先介紹一下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;//如果沒有通過三審的訂單要發送,則返回不發送郵件
        }
        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.NET\Framework\v2.0.50727\CONFIG\ 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郵箱都可以實現發送郵件的功能,大家可否討論下他們是怎樣實現的。

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.