2012-01-10 6 views
2

私のアプリケーションでは、約100ミリ秒以内に約100件のバッチジョブが要求されますが、実際にはこれらのジョブ要求は1つのジョブ要求としてマスクされています。 現時点では、1つのジョブ要求のみが実行可能でないように、この問題を修正してください。ASP.NET:バッチジョブの実行

私が考えていた回避策は、アプリケーションがxミリ秒ごとに1回のバッチジョブしか実行しないようにプログラムすることです。この場合は200ミリ秒と考えていましたが、200ミリ秒私のバッチジョブが完了したとき。それらの200ミリ秒が稼働した後、またはバッチジョブが完了した後、私のアプリケーションはその時から1つのジョブ要求を待って受け入れ、前に無視された要求を処理しません。私のアプリケーションが別のジョブ要求を受け入れると、上記のサイクルが繰り返されます。

.Net 4.0を使用してこれを行う最善の方法は何ですか?私がガイドとして単に従うことができるボイラプレートのコードはありますか?

更新 ご迷惑をおかけして申し訳ありません。私は私のシナリオについての詳細を追加しました。また、私は、上記の私の提案した回避策がうまくいかないことに気付きました。ごめんなさい、笑。ここに背景情報があります。

私は指定されたディレクトリのファイルを使用してインデックスを構築するアプリケーションを持っています。ファイルがこのディレクトリで追加、削除、または変更されると、アプリケーションはFileSystemWatcherを使用してこれらのイベントをリッスンし、これらのファイルを再インデックスします。問題は、およそ100のファイルが外部プロセスによって追加、削除、または変更され、非常に迅速に発生することです。すなわち、数ミリ秒以内に発生します。私の最終目標は、最後のファイル変更が外部プロセスによって発生した後にこれらのファイルのインデックスを再作成することです。最善の解決策は、私が聞いているファイルの変更が完了した時点でアプリケーションに信号を送るために外部プロセスを変更することですが、現時点では実現不可能です。したがって、私は回避策を作成する必要があります。

私の問題を解決する可能性のある回避策は、最初のファイル変更を待つことです。最初のファイル変更が発生した場合は、その後のファイル変更が200ミリ秒待機します。なぜ200ミリ秒でしょうか?なぜなら、外部プロセスが200ミリ秒以内にファイルの変更を実行できることを望んでいるからです。私のアプリケーションが200ミリ秒待ってから、ファイルのインデックスを再作成し、ファイルの変更を聞く別のサイクルを経るタスクを開始したいと思います。

これを行う最善の方法は何ですか?

もう一度、混乱して申し訳ありません。

+0

私は200msのための要求を遅らせることは解決する方法が表示されません症状。ワークフローを再設計する必要があるように思えます。そうしないと、後で同じ状況になることがあります。症状を回避するのではなく、問題を解決するのはなぜですか? –

答えて

0

この質問はあまりにも高すぎると推測することはできません。

私の推測では、あなたのアプリケーションはサービスとして実行されているので、あなたの要求はアプリケーションに入り、処理される待ち行列に到着します。そして、200ミリ秒ごとに、待ち行列を目覚めさせ、処理のためにポップしてアイテムを消します。

「1つのジョブリクエストとしてマスクされました」と混同しています。あなたが "他のバッチジョブを無視する"と言いましたので、キューに入ってくるリクエストを受け入れるようにコードを配置していないと思います。

通常、常に1つのアプリケーションプロセス(サービス)が実行され、選択すると、キューで処理する各アイテムに対して新しいスレッドが生成されます。これに必要なCPU /メモリ使用量を監視し、それに応じて発射時間(200ms)を調整することができます。

0

私は問題を正確に理解していないかもしれませんが、この問題を回避するためにシングルトンパターンを使用することをお勧めします。

シングルトンアプローチでは、オブジェクトにロックを実装できます(アクセスメソッドはBatchProcessor :: GetBatchResultsの行にある可能性があります)。その結果、すべての要求がバッチジョブ結果オブジェクトにロックされます。バッチが完了すると、ロックが解除され、基礎となるオブジェクトはバッチジョブの結果を利用できます。

これは「回避する」ことに注意してください。オンデマンドで処理されているジョブに対して複数の要求が入る原因となるビジネスロジックの調査と変更が必要な場合は、より良い解決策があります。

アップデート:ここで はシングルトン(コード例を含み)に関する情報へのリンクです:http://msdn.microsoft.com/en-us/library/ff650316.aspx

0

それはポスターが実行する着信要求のために座って待つアプリケーションのいくつかの並べ替えを持っていることを私の理解でありますバッチジョブ。短期間に複数のリクエストを受け取り、実際にはただ1つのリクエストとして受け取らなければならないという問題。残念ながら、彼はこの問題を解決することはできません。

したがって、彼の解決策は、200 msの時間間隔内に受信されたすべての要求が同じであると仮定し、これらを一度だけ処理することです。私の心配は、この仮定が正しいかどうかです。これは、送信システムとこれが使用されている環境に完全に依存します。これを行うための一般的な考え方は、リクエストが処理されたときのlastReceivedの日時を更新することです。新しいリクエストが来たら、現在の日付/時刻をlastReceivedの日付/時刻と比較し、その差が200ミリ秒より大きい場合にのみ処理します。

他の可能な解決策は:

  1. あなたはとても1件のジョブのみリクエストが送信された送信側のアプリケーションを変更することができないと言いましたが、あなたは、例えば、それに一意の識別子を付加的な情報を追加することができますか?

  2. 最後のジョブ要求のパラメータを保存し、次のジョブ要求と比較して、それらが異なる場合にのみ処理できますか?ここで

あなたの更新に基づいて

あなたはタイマーを使用して200ミリ秒を待つことができる方法の例です:

static Timer timer; 
    static int waitTime = 200; //in ms 

    static void Main(string[] args) 
    { 
     FileSystemWatcher fsw = new FileSystemWatcher(); 
     fsw.Path = @"C:\temp\"; 
     fsw.Created += new FileSystemEventHandler(fsw_Created); 
     fsw.EnableRaisingEvents = true; 

     Console.ReadLine(); 
    } 

    static void fsw_Created(object sender, FileSystemEventArgs e) 
    { 
     DateTime currTime = DateTime.Now; 

     if (timer == null) 
     { 
      Console.WriteLine("Started @ " + currTime); 

      timer = new Timer(); 
      timer.Interval = waitTime; 
      timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
      timer.Start(); 

     } 
     else 
     { 
      Console.WriteLine("Ignored @ " + currTime); 
     } 
    } 

    static void timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     //Start task here 

     Console.WriteLine("Elapsed @ " + DateTime.Now); 
     timer = null; 
    } 
+0

あなたは私の問題を最もよく理解していると思います。私は1)と2)をすることができます。バッチジョブを完全に制御し、その動作を変更します。 私が提案した最初の回避策は動作しません。 2番目の回避策があります。これには、バッチジョブを200ミリ秒待機した後に、バッチジョブを200ミリ秒待ってから発射することに反対する発砲が含まれます。 – burnt1ce

+0

上記の例はあなたの質問に答えましたか? – jzacharuk

関連する問題