.NETシステム計画タスク(整理版)

11466 ワード

C#で計画タスクをどのように実現しますか?複雑なアプリケーションでは、データベースのバックアップ、Eメールのタイミング送信、データのクリアなど、1つ以上のタスクを一定時間または間隔で計画する必要がある場合があります.計画タスクの実装には、SQLAgentがストレージ・プロシージャを実行して実装したり、Windowsの計画タスクで実装したりする方法がたくさんあります.Webアプリケーションでは、実装が簡単ではありませんが、Webアプリケーションで現在計画されているタスクの2つの方法について説明します.
ASP.NETサイトはWebアプリケーションとして実行されており、スレッドに制限されていないため、Application_StartとApplication_Endイベントで計画タスクを確立および破棄します.Webサイトで計画タスクを実現する方法を簡単に紹介します.我々の例は,定期的にファイルに情報を追加する例であり,ここでは現在の時間を定期的にファイルに書き込む.
1つの計画タスクの作業ユニットは1つのタスク(Job)と呼ばれ、以下のコードはすべてのタスクをスケジューリングエンジンによって計画的に実行できる共通のインタフェースを説明し、ここで各タスクはExecuteメソッドを実現し、スケジューリングエンジンによって呼び出される.
    public   interface   ISchedulerJob    

    {    

      void   Execute();    

    }   


前述したように、私たちの例は、文字の日付のようなファイルへの書き込みを実現することです.次に、このタスクを実現する方法を示します.
    public   class   SampleJob   :   ISchedulerJob    

    {    

      public   void   Execute()    

      {    

        //         ,CSTest       ,F:\Inetpub\wwwroot\CSTest         

        string   p   =   @"F:\Inetpub\wwwroot\CSTest";    

        //              SchedulerJob   ,           ,    

        //SchedulerJob.txt             

        string   FILE_NAME   =   p+   "http://www.cnblogs.com/dajiang02/admin/file://schedulerjob//SchedulerJob.txt";    

        //         ,           

        string   c   =   System.DateTime.Now.ToString("yyyy-mm-dd   hh:MM:ss");    

        //                

        bool   flag   =   false;    

        //       ,          

        if   (!File.Exists(FILE_NAME))    

        {    

          flag   =   true;    

          StreamWriter   sr   =   File.CreateText(FILE_NAME);    

          sr.Close();    

        }    

        //           

        StreamWriter   x   =   new   StreamWriter(FILE_NAME,true,System.Text.Encoding.Default);    

        if(flag)   x.Write("        :");    

        x.Write("\r
"+c); x.Close(); } }

次に、スケジューリングエンジンがどのタスクを実行するかと実行する間隔を示す構成オブジェクトを作成します.   
    public   class   SchedulerConfiguration    

    {    

      //        

      private   int   sleepInterval;    

      //        

      private   ArrayList   jobs   =   new   ArrayList();    

     

      public   int   SleepInterval   {   get   {   return   sleepInterval;   }   }    

      public   ArrayList   Jobs   {   get   {   return   jobs;   }   }    

     

      //              

      public   SchedulerConfiguration(int   newSleepInterval)    

      {    

        sleepInterval   =   newSleepInterval;    

      }    

    }    


次はスケジューリングエンジンで、構成オブジェクトのタスクをタイミングよく実行します.
    public   class   Scheduler    

    {    

      private   SchedulerConfiguration   configuration   =   null;    

     

      public   Scheduler(SchedulerConfiguration   config)    

      {    

        configuration   =   config;    

      }    

     

      public   void   Start()    

      {    

        while(true)    

        {    

          //           

          foreach(ISchedulerJob   job   in   configuration.Jobs)    

          {    

            ThreadStart   myThreadDelegate   =   new   ThreadStart(job.Execute);    

            Thread   myThread   =   new   Thread(myThreadDelegate);    

            myThread.Start();    

            Thread.Sleep(configuration.SleepInterval);    

          }    

        }    

      }    

    }    


すべての準備が完了しました.次はエンジンをアクティブにする作業です.私たちの任務計画を実行するためにGlobalにいます.asax.csファイルのApplicatio_StartとApplication_Endでは作成と破棄を行い、まずスケジューリングプロセスの実行スレッドを作成します.ここでの実行間隔は3秒です. 
      public   System.Threading.Thread   schedulerThread   =   null;    

      protected   void   Application_Start(Object   sender,   EventArgs   e)    

      {    

          SchedulerConfiguration   config   =     new   SchedulerConfiguration(1000*3);    

          config.Jobs.Add(new   SampleJob());    

          Scheduler   scheduler   =   new   Scheduler(config);    

          System.Threading.ThreadStart   myThreadStart   =     new   System.Threading.ThreadStart(scheduler.Start);    

          System.Threading.Thread   schedulerThread   =   new   System.Threading.Thread(myThreadStart);    

          schedulerThread.Start();    

      }    

     

               :    

     

      protected   void   Application_End(Object   sender,   EventArgs   e)    

      {    

          if   (null   !=   schedulerThread)    

          {    

              schedulerThread.Abort();    

          }    

      }    


さて、VS.NETでC#のWebアプリケーションエンジニアリングを構築し、TaskSchedulerを構築します.csクラスを変更し、対応するGlobalを変更します.asax.csファイル.効果を見るためにフォームWebForm 1を作成します.aspx、タイミングリフレッシュで記録されたデータを確認します.
<%@   Page   language="c#"   Codebehind="WebForm1.aspx.cs"   AutoEventWireup="false"    

    Inherits="CSTest.WebForm1"   %>    

<!DOCTYPE   HTML   PUBLIC   "-//W3C//DTD   HTML   4.0   Transitional//EN"   >    

<HTML>    

      <HEAD>    

          <title> Web              </title>    

          <meta   http-equiv="refresh"   content="10">    

          <meta   name="GENERATOR"   Content="Microsoft   Visual   Studio   7.0">    

          <meta   name="CODE_LANGUAGE"   Content="C#">    

          <meta   name="vs_defaultClientScript"   content="JavaScript">    

          <meta   name="vs_targetSchema"   content="http://schemas.microsoft.com/intellisense/ie5">    

      </HEAD>    

      <body   MS_POSITIONING="GridLayout">    

          <form   id="Form1"   method="post"   runat="server">    

              <iframe   style="width:100%;height:100%"   src="SchedulerJob/SchedulerJob.txt"></iframe>    

          </form>    

      </body>    

</HTML>    


プロジェクトをコンパイルして実行すると、結果が表示されます.結果は次のとおりです.
計画タスクテスト開始:2003-13-10 11:08:15 2003-13-10 11:08:18 2003-13-10 11:08:21 2003-13-10 11:08:24 2003-13-10 11:08:27 2003-13-10 11:08:30説明する必要があるのは、以上はWebアプリケーションで計画タスクを実行する簡単な例にすぎず、複数のタスクにとって異なるスレッド内で作業する必要があることです.計画の手配も簡単で、実際にはサイトが詰まっていて、その場にいる場合も必要です.また、ここではエラー処理などの作業も行われておらず、より完璧なコードが書けると信じています.
 
次は、マルチタスクを実行でき、時間を隔てて実行できる計画タスクです.(上記と同じ方法ではありません)
using System.Collections;

using System.Threading;



namespace Metrial

{

    /// <summary>

    /// TaskScheduler      

    /// </summary>

    public class TaskScheduler

    {

        /// <summary>

        ///       

        /// </summary>

        public interface ISchedulerJob

        {

            /// <summary>

            ///     

            /// </summary>

            void Execute();

        }



        /// <summary>

        ///   sample1

        /// </summary>

        public class Method1 : ISchedulerJob

        {

            public void Execute()

            {

                //         1

            }

        }



        /// <summary>

        ///   sample2

        /// </summary>

        public class Method2 : ISchedulerJob

        {

            public void Execute()

            {

                //         2

            }

        }





        //    ,          ,                    。

        /// <summary>

        /// 

        /// </summary>

        public class SchedulerConfiguration

        {

            //    

            //    

            /// <summary>

            /// 

            /// </summary>

            private readonly ArrayList jobs = new ArrayList();



            /// <summary>

            ///         

            /// </summary>

            /// <value>The sleep interval.</value>

            public int SleepInterval { get; private set; }



            /// <summary>

            ///         

            /// </summary>

            /// <value>The jobs.</value>

            public ArrayList Jobs { get { return jobs; } }



            public SchedulerConfiguration(int newSleepInterval)

            {

                SleepInterval = newSleepInterval;

            }

        }



        //        ,           

        /// <summary>

        /// 

        /// </summary>

        public class Scheduler

        {

            /// <summary>

            /// 

            /// </summary>

            private readonly SchedulerConfiguration configuration;



            /// <summary>

            /// Initializes a new instance of the <see cref="Scheduler"/> class.

            /// </summary>

            /// <param name="config">The config.</param>

            public Scheduler(SchedulerConfiguration config)

            {

                configuration = config;

            }



            /// <summary>

            /// Starts this instance.

            /// </summary>

            public void Start()

            {

                while (true)

                {

                    //       

                    foreach (ISchedulerJob job in configuration.Jobs)

                    {

                        var myThreadDelegate = new ThreadStart(job.Execute);

                        var myThread = new Thread(myThreadDelegate);

                        myThread.Start();

                    }

                    Thread.Sleep(configuration.SleepInterval);

                }

            }

        }

    }

}


 
最後にGlobalでasaxのApplication_StartイベントでTaskメソッドが呼び出されます.
 
public void Task()

        {

            var config = new TaskScheduler.SchedulerConfiguration(1000 * 60 * 10);

            config.Jobs.Add(new TaskScheduler.Method1());

            config.Jobs.Add(new TaskScheduler.Method2());

            var scheduler = new TaskScheduler.Scheduler(config);

            var myThreadStart = new System.Threading.ThreadStart(scheduler.Start);

            var schedulerThread = new System.Threading.Thread(myThreadStart);

            schedulerThread.Start();

        }


 
もう一つの深刻な問題は、IISが一定期間稼働すると、計画タスクが自動的に停止することです.なぜなら、IISアプリケーションプールの定期的な回収により、計画タスクが自動的に停止したためです.Application_Endに次のコードを追加します.
 
//        ,   IIS            

Thread.Sleep(1000);

//      web  ,            aspx          ,      Application_Start

string url = "http://localhost:82/111.aspx";

HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);

HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

Stream receiveStream = myHttpWebResponse.GetResponseStream();//        


 
原理:Global.asaxはaspである.Netのアプリケーションまたはセッションイベントハンドラで、Application_を使用しました.Start(アプリケーション開始イベント)とApplication_End(アプリケーション終了イベント).アプリケーションが開始されると、タスクYourTask()メソッドを実行するためのタイマが起動します.このメソッドには、呼び出しが必要な論理コードを書くことができます.単一スレッドとマルチスレッドです.アプリケーションが終了すると、IISなどのアプリケーションプールが回収するasp.Netは現在のこのwebアドレスにアクセスして、ローカルテストの時にローカルアドレスを書いて、例えばhttp://localhost:82/111.aspxあ、本番環境になると、あなたのwebアドレスに変更できます.ここではaspxページにアクセスして、アプリケーションを再アクティブにする必要があります.
 
PS:いろいろな方法を参考にして、コードや先辈たちの経験も整理しました.この文章は私が选んだ3つの文章がいいと思って私有化した结果です.整理したコードはテスト后に削除されました.今は直接Ctrlにコードを渡しています.皆さん、助けてください.