熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

各種ASP.NET定時執行任務解決方案收集

2013-11-13 10:27:50  來源: .NET編程 

  方法一

  using System;

  using SystemData;

  using SystemConfiguration;

  using SystemCollections;

  using SystemWeb;

  using SystemWebSecurity;

  using SystemWebSessionState;

  using SystemTimers;

  using SystemNet;

  using SystemIO;

  using SystemText;

  using SystemThreading;

  namespace

  {

  public class Global : SystemWebHttpApplication

  {

  protected void Application_Start(object sender EventArgs e)

  {

  //定義定時器

  SystemTimersTimer myTimer = new SystemTimersTimer();

  myTimerElapsed += new ElapsedEventHandler(myTimer_Elapsed);

  myTimerEnabled = true;

  myTimerAutoReset = true;

  }

  void myTimer_Elapsed(object source ElapsedEventArgs e)

  {

  try

  {

  LogSaveNote(DateTimeNowToString(yyyyMMdd HH:mm:ss) + :AutoTask is Working!);

  YourTask();

  }

  catch (Exception ee)

  {

  LogSaveException(ee);

  }

  }

  void YourTask()

  {

  //在這裡寫你需要執行的任務

  }

  protected void Application_End(object sender EventArgs e)

  {

  LogSaveNote(DateTimeNowToString(yyyyMMdd HH:mm:ss) + :Application End!);

  //下面的代碼是關鍵可解決IIS應用程序池自動回收的問題

  ThreadSleep();

  //這裡設置你的web地址可以隨便指向你的任意一個aspx頁面甚至不存在的頁面目的是要激發Application_Start

  string url =

  HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequestCreate(url);

  HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequestGetResponse();

  Stream receiveStream = myHttpWebResponseGetResponseStream();//得到回寫的字節流

  }

  }

  }

  原理Globalasax 可以是中應用程序或會話事件處理程序我們用到了Application_Start(應用程序開始事件)和Application_End(應用程序結束事件)當應用程序開始時啟動一個定時器用來定時執行任務YourTask()方法這個方法裡面可以寫上需要調用的邏輯代碼可以是單線程和多線程當應用程序結束時如IIS的應用程序池回收讓去訪問當前的這個web地址這裡需要訪問一個aspx頁面這樣就可以重新激活應用程序Log類是一個記錄日志的一個類下面是測試時生成的日志信息

  ================================================================

   :::AutoTask is Working!

   :::AutoTask is Working!

   :::AutoTask is Working!

   :::Application End!

   :::AutoTask is Working!

   :::AutoTask is Working!

  從日志中發現當手動回收IIS的應用程序池之後計劃任務還在執行說明我們的目的達到了

  如果將Application_End中的代碼注釋掉會發現Application End之後計劃任務停止工作了如下

  ================================================================

   :::AutoTask is Working!

   :::AutoTask is Working!

   :::AutoTask is Working!

   :::Application End!

  局限性可以解決應用程序池自動或者手動回收但是無法解決IIS重啟或者web服務器重啟的問題當然這種情況出現的時候不多而且如果有人訪問你的網站的時候又會自動激活計劃任務了

  方案二

  <%@ Application Language=C# %>

  <%@ import Namespace=SystemIO %>

  <script runat=server>

  void Application_Start(object sender EventArgs e)

  {

  // 在應用程序啟動時運行的代碼

  SystemTimersTimer myTimer = new SystemTimersTimer();

  myTimerElapsed += new SystemTimersElapsedEventHandler(OnTimedEvent);

  myTimerInterval = ;

  myTimerEnabled = true;

  }

  void Application_End(object sender EventArgs e)

  {

  //  在應用程序關閉時運行的代碼

  }

  void Application_Error(object sender EventArgs e)

  {

  // 在出現未處理的錯誤時運行的代碼

  }

  void Session_Start(object sender EventArgs e)

  {

  // 在新會話啟動時運行的代碼

  }

  void Session_End(object sender EventArgs e)

  {

  // 在會話結束時運行的代碼

  // 注意: 只有在 nfig 文件中的 sessionstate 模式設置為

  // InProc 時才會引發 Session_End 事件如果會話模式設置為 StateServer

  // 或 SQLServer則不會引發該事件

  }

  private static void OnTimedEvent(object source SystemTimersElapsedEventArgs e)

  {

  //間隔時間執行某動作

  //指定日志文件的目錄

  string fileLogPath = AppDomainCurrentDomainBaseDirectory + SystemLog;

  string fileLogName = SoftPrj_CN_ + DateTimeNowToLongDateString() + _logtxt;

  //定義文件信息對象

  FileInfo finfo = new FileInfo(fileLogPath + fileLogName);

  //創建只寫文件流

  using (FileStream fs = finfoOpenWrite())

  {

  //根據上面創建的文件流創建寫數據流

  StreamWriter strwriter = new StreamWriter(fs);

  //設置寫數據流的起始位置為文件流的末尾

  strwriterBaseStreamSeek( SeekOriginEnd);

  //寫入錯誤發生時間

  strwriterWriteLine(發生時間: + DateTimeNowToString());

  //寫入日志內容並換行

  //strwriterWriteLine(錯誤內容: + message);

  strwriterWriteLine(錯誤內容: );

  //寫入間隔符

  strwriterWriteLine();

  strwriterWriteLine();

  //清空緩沖區內容並把緩沖區內容寫入基礎流

  strwriterFlush();

  //關閉寫數據流

  strwriterClose();

  fsClose();

  }

  }

  </script>

  方案三

  <%@ Application Language=C# %>

  <%@ Import Namespace=SystemIO %>

  <%@ Import Namespace=SystemThreading %>

  <script RunAt=server>

  string LogPath;

  Thread thread;

  void WriteLog()

  {

  while (true)

  {

  StreamWriter sw = new StreamWriter(LogPath true EncodingUTF);

  swWriteLine(threadName + : + DateTimeNowToString());

  swClose();

  ThreadCurrentThreadJoin( * );//阻止

  }

  }

  void Application_Start(object sender EventArgs e)

  {

  LogPath = HttpContextCurrentServerMapPath(logtxt);        //在應用程序啟動時運行的代碼

  thread = new Thread(new ThreadStart(WriteLog));

  threadName = 寫登錄日志線程;

  threadStart();

  }

  void Application_End(object sender EventArgs e)

  {

  //  在應用程序關閉時運行的代碼

  }

  void Application_Error(object sender EventArgs e)

  {

  // 在出現未處理的錯誤時運行的代碼

  }

  void Session_Start(object sender EventArgs e)

  {

  // 在新會話啟動時運行的代碼

  }

  void Session_End(object sender EventArgs e)

  {

  // 在會話結束時運行的代碼

  // 注意: 只有在 nfig 文件中的 sessionstate 模式設置為

  // InProc 時才會引發 Session_End 事件如果會話模式設置為 StateServer

  // 或 SQLServer則不會引發該事件

  }

  </script>


From:http://tw.wingwit.com/Article/program/net/201311/13724.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.