0


1

仕事を始める要求を受け付けるWCFアプリがあります。 各仕事はちょうどX分後に何かをする必要があります(例: 5分)、仕事の依頼もいつでも、同時にすることができます。

これは私が念頭に置いていることです、

// WCF class
public class RequestManager {// WCFメソッドpublic void StartNewJob(){//各ジョブのタイマーで新しいスレッドを開始しますか? }}

パブリッククラスJob {public Job(){//いくつかの初期化を行います

// x分後に何かする

//スリープまたはタイマー? }

private void DoSomething(){//フォローアップを行います}}

私のアプローチでは、X分には何もしないスレッドが多すぎることが怖いです。 1秒あたりの精度も必要条件となります(0:05:01にジョブを開始し、フォローアップは0:10:01になるはずです)。

これに取り組むための最善の方法は何でしょうか。

4 Answer


1


あなたは Timerクラスのシリーズが必要なように思える:

// WCF class
パブリッククラスRequestManager {// WCFメソッドpublic void StartNewJob(){Job myJob = new Job(); // myJobを初期化します... myJob.Start(); }}

パブリッククラスJob {private Timer myTimer = new Timer();

public Job(){myTimer.Elapsed = new ElapsedEventHandler(this.OnTimedEvent); }

public void Start(int Miniutes){myTimer.Interval = 60000 *ミニッツ。 myTimer.Enabled = true; }

private static void OnTimedEvent(オブジェクトソース、ElapsedEventArgs e){//なにか}

上記のコードは、以下のことを前提としています。

  1. あなたは同じtimerインスタンス上でStart()を二度呼び出す試みのような愚かなことはしないでください。

  2. アプリケーションの他の場所でアクティブな他のバックグラウンド以外のスレッドがアプリケーションの終了を妨げています。

その完全な例ではありませんが、うまくいけばそれはあなたに考えを与えるべきです - Timerクラスは各ジョブのためにアクティブなスレッドを必要とせずに時間を保つことを扱うでしょう。


1


http://msdn.microsoft.com/en-us/library/shfwcf8k.aspx[RegisterWaitForSingleObject]関数を見てください。
var waitObject = new AutoResetEvent(false);

// Execute the callback on a new thread 10 seconds after this call
// and execute it only once
ThreadPool.RegisterWaitForSingleObject(waitObject、(state、timeout)=> {Console.WriteLine( "ok");}、null、TimeSpan.FromSeconds(10)、true);

// Execute the callback on a new thread 10 seconds after this call
// and continue executing it at 10 seconds intervals until the
// waitHandle is signaled.
ThreadPool.RegisterWaitForSingleObject(waitObject、(state、timeout)=> {Console.WriteLine( "ok");}、null、TimeSpan.FromSeconds(10)、false);


0


Quartz.NETなどのタイミング/スケジューリングフレームワークを使用するか、独自のもの(軽量)を作成する必要があります。


0


タイマーを使うのは私にとっては良いこと(そして実装がより簡単であること)のようです。

NETで使用できるタイマークラスはいくつかあります。 次のドキュメントを参照してください(少々古くなっていますが、良いスタートのようです)。http://msdn.microsoft.com/en-us/magazine/cc164015.aspxフレームワーククラスライブラリ]

ただし、スレッドのウェイクアップ時およびJob.DoSomethig()の完了時にタイムスタンプを取得しながらオフセットを計算することで、Thread.Sleep()でもこの動作を実現できます。

以下のことを注意深く検討することをお勧めします。

  1. Job.DoSomething()を実行するスレッド間の競合はありますか?

  2. 次のシナリオでは細心の注意を払う必要があります。Job.DoSomething()が期間より長くかかることがある場合(つまり、 上の例では0:05から始まり0:13を完了しています。 これはあなたのアプリケーションにとってどのような意味があり、どのように処理されるのでしょうか。 {空} 完全な失敗 - 0:10に現在の(0:05)実行を中止し、0:10実行を開始 {空} b 大したことではありません(0:10をスキップして、Job.DoSomething()を0:15に実行してください)。 {空} c。 大したことではありませんが、0:05のタスクが終了した直後に0:10の実行を開始する必要があります(5秒以上かかる場合はどうでしょうか)。 {空} d。 0:05実行が現在実行中でも、0:10実行を起動する必要があります。 {空} e 他に何か?

上記で選択したポリシーについて、選択した実装(上記のいずれかのタイマークラスまたはThread.Sleep()のいずれか)でポリシーを簡単にサポートできますか?