asp.Net計画タスク管理プログラム実装、マルチスレッドタスクロード

7208 ワード

asp.Netの下で実現はタスクを計画する方法をglobalの中に置くことができて、1つの統一的なタスク管理クラスを使って各種のタスクの実行を管理して、並行して矛盾しないようにします!
次は私が書いた方法で、レンガを投げて玉を引く役割を果たしたいと思っています.みんなで勉強します.
最初のステップでは、タスクが実行しなければならないアクションを規範化するためのインタフェースを定義します.このインタフェースには、1つの方法しかありません(単純化のため).
 
  
///
/// ,
///

public interface IScheduledTask
{
///
///
///

void Execute();
}

ステップ2では、計画タスクの実行とクローズを管理するクラスを定義します.
 
  
///
///
///

public class ScheduledTask
{
private static readonly ScheduledTask _ScheduledTask = null;

private Timer UpdateTimer = null;

///
/// ,
///

private int interval = 10 * 1000;
///
/// ,
///

public int Interval
{
get { return this.interval; }
set { this.interval = value; }
}
///
///
///

private int _IsRunning;

///
/// ,
///

static ScheduledTask()
{
_ScheduledTask = new ScheduledTask();
}
///
///
///

private ArrayList tasks = new ArrayList();
///
///
///

public ArrayList Tasks { get { return tasks; } }

///
///
///

///
public static ScheduledTask Instance()
{
return _ScheduledTask;
}

///
///
///

public void Start()
{
if (UpdateTimer == null)
{
UpdateTimer = new Timer(new TimerCallback(UpdateTimerCallback), null, interval, interval);
}
}

///
///
///

///
private void UpdateTimerCallback(object sender)
{
if (Interlocked.Exchange(ref _IsRunning, 1) == 0)
{
try
{
//
foreach (IScheduledTask task in Tasks)
{
ThreadStart myThreadDelegate = new ThreadStart(task.Execute);
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
}
}
catch (Exception ex)
{
//
CreateLog(ex.Message, true);
}
finally
{
Interlocked.Exchange(ref _IsRunning, 0);
}
}
}

///
///
///

public void Stop()
{
if (UpdateTimer != null)
{
UpdateTimer.Dispose();
UpdateTimer = null;
}
}

///
///
///

///
///
public static void CreateLog(string message, bool iserror)
{
DateTime dt = DateTime.Now;
int y = dt.Year;//
int m = dt.Month;//

string root = HttpRuntime.AppDomainAppPath;

root += "ScheduledTaskLogs";

if (!File.Exists(root)) Directory.CreateDirectory(root);

string dir_y = root + "\\" + y.ToString();
string dir_m = dir_y + "\\" + m.ToString();
string err = iserror ? "_taskerror" : "_task";
string dirOk = dir_m + "\\" + dt.Year + dt.Month + dt.Day + err + ".txt";

//
if (!File.Exists(dir_y)) Directory.CreateDirectory(dir_y);

//
if (!File.Exists(dir_m)) Directory.CreateDirectory(dir_m);

string err1 = iserror ? " " : "";

if (File.Exists(dirOk))
{
StreamWriter sr = new StreamWriter(dirOk, true, Encoding.Default);
lock (sr)
{
sr.WriteLine();
sr.WriteLine("-------------- " + err1 + " -----------------------------------------------------------------------");
sr.WriteLine(err1 + " : " + DateTime.Now.ToString());
sr.WriteLine(" : " + message);
sr.WriteLine("--------------------------------------------------------------------------------------------");
}
sr.Close();
sr.Dispose();
}
else
{
StreamWriter sr = new StreamWriter(dirOk, false, Encoding.Default);
lock (sr)
{
sr.WriteLine();
sr.WriteLine("-------------- " + err1 + " -----------------------------------------------------------------------");
sr.WriteLine(err1 + " : " + DateTime.Now.ToString());
sr.WriteLine(" : " + message);
sr.WriteLine("--------------------------------------------------------------------------------------------");
}
sr.Close();
sr.Dispose();
}
}
}

ステップ3では、動作処理クラスを定義し、ステップ1で定義したインタフェースを継承します.次の例は、所定の時間帯にメール送信を実行するタイミングメール送信プログラムです.
 
  
///
/// --
///

public class Task_MailSend : IScheduledTask
{
public void Execute()
{
string nw = DateTime.Now.ToString("HH");

int hh = 0;
if (!Int32.TryParse(nw, out hh)) { return; }

// 11-13
if (hh < 10 || hh > 17)
{
ScheduledTask.CreateLog(" ", true);
return;
}

DataTable dt = GetOrderedUser();
int num = dt.Rows.Count;
if (num == 0)
{
ScheduledTask.CreateLog(" ", true);
return;
}
/*

mail 。。。
*/
}

さあ、上の3つのステップを実行した後、残りの仕事はglobalに任せます!
 
  
<!-- <br> <br>void Application_Start(object sender, EventArgs e) <br>{ <br>// <br>//WildRen.Common <br>WildRen.Common.ScheduledTask.Instance().Interval = 12 * 60 * 60000;// <br>WildRen.Common.ScheduledTask.Instance().Tasks.Add(new Task_MailSend());// <br>WildRen.Common.ScheduledTask.Instance().Start();// <br>} <br> <br>void Application_End(object sender, EventArgs e) <br>{ <br>// <br>WildRen.Common.ScheduledTask.Instance().Stop(); <br> <br>} <br> <br>// -->

ajaxを使用してこの管理クラスのシミュレーションクライアントtimerイベントに接続する場合は、行処理も可能です.もちろん方法は唯一ではありません.このプログラムにはいくつかの不足点があるかもしれません.皆さんの指摘を歓迎します.