0

これは、キューのセットアップです。

  1. キューはパブリックであり、トランザクションとしてマークされています。
  2. Web サービスは、メッセージをキューに挿入する役割を果たします。
  3. Windows サービスがキューでリッスンしています

では、20 分以上経過したメッセージのみを処理するにはどうすればよいでしょうか?

4

3 に答える 3

1

キューが先入れ先出しであるとすると、キュー内のすべてのメッセージは、キュー内の最初のメッセージと同じかそれ以降の時間に到着すると想定する必要があります。

あなたはそれをあなたの利益のために使うことができます。

基本的に、MessageQueueインスタンスでPeekメソッドを呼び出し、ArrivedTimeプロパティを確認します。現在から到着時刻までの時間が20分を超える場合は、それを処理します。それ以外の場合は、(次にキューでメッセージを処理するまで)待機し続けます。

次に例を示します。

static Message GetQueueMessage(MessageQueue queue)
{
  // Store the current time.
  DateTime now = DateTime.Now;

  // Get the message on top of the queue.
  Message message = queue.Peek();

  // If the current time is greater than or equal to 20 minutes, then process it,
  // otherwise, get out and return false.  Generate 20 minutes first.
  // You can refactor this to have it passed in.
  TimeSpan delay = TimeSpan.FromMinutes(20);

  // If the delay is greater than the arrived time and now, then get out.
  if (delay > (now - message.ArrivedTime))
  {
    // Return null.
    return null;
  }

  // Pop the message from the queue to remove it.
  return queue.ReceiveById(message.Id);    
}

次に、これをループで実行し、その間に少し待機します(5秒ごと、10秒ごと、処理の頻度に適していると思われるものは何でも)。

// Have some other reasonable check here.
do while (true)
{
  // The message to process.
  Message message = GetQueueMessage(queue);

  // Continue to process while there is a message.
  do while (message != null)
  {
    // Process the message.

    // Get the next message.
    message = GetQueueMessage(queue);
  }

  // Wait a little bit, five seconds for example.
  Thread.Sleep(5000);
}

理想的には、 Charles Conwayのコメントに基づいて、これをループで処理するのではなく、指定された間隔で起動するタイマーのイベントハンドラーからGetQueueMessageを呼び出すだけです。

于 2009-01-21T19:21:08.010 に答える
1
// Have some other reasonable check here.
do while (true)
{
...
}

ブール状態で「true」になるのはコードの臭いです...タイマーを使用して5秒ごとにウェイクアップすることを検討しましたか?

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

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
   // The message to process.
   Message message = GetQueueMessage(queue);

    // Continue to process while there is a message.
   do while (message != null)
   {
   // Process the message.

   // Get the next message.
   message = GetQueueMessage(queue);
   }

}
于 2009-01-21T19:28:29.727 に答える
0

これの警告は、どの時点で20分経過したと定義していますか?

ケース1:メッセージが生成および送信された日時に基づいて定義されている場合は、Message.SentTimeを使用する必要があります。次に、Peekを使用してメッセージを確認し、20分のしきい値に達するまで処理を遅らせることができます。 これは、メッセージが線形の順序で到着することを前提としていますが、これは保証されていません。(下記参照。)

ケース2:メッセージがキューに到着するタイミングに基づいて定義されている場合は、Message.ArrivedTime(IEプロセスがメッセージキューを「リッスン」している)の時間を記録し、20分後に消費します。

しかし...どちらの場合も、最初のメッセージしか覗くことができないため、問題が発生します。そのため、指定された時間に処理するために、メッセージをキューまたは他の構造に消費する必要があります。

于 2009-01-21T19:20:17.077 に答える