2012-04-26 24 views
9

n個のメッセージキューからメッセージを受信するサービスがあります。ただし、メッセージキューサービスが再起動されると、メッセージ取得サービスはメッセージキューサービスが正常に再開した後でもメッセージの受信を停止します。メッセージキューサービスの再起動後にサービスがメッセージを受信しない

メッセージ検索サービスでスローされたMessageQueueExceptionを具体的に捕捉し、キューのBeginReceiveメソッドを再び呼び出そうとしました。しかし、メッセージキューサービスが再起動するのに2秒かそこらで、私は、約1875インスタンスの例外を取得し、StartListeningメソッドで別のMessageQueueExceptionがスローされたときにサービスが機能しなくなります。

メッセージキューサービスの再起動から回復するための洗練された方法はありますか?

この無限ループの問題に対処する必要がありますが、これは少し問題がありますが、あなたはそのアイデアを得ます。

MessageQueueExceptionが発生した場合は、RecoverQueueメソッドを呼び出します。サービスの再起動の結果である例外を受け取ると

private void RecoverQueue(MessageQueue queue) 
    {    
     string queuePath  = queue.Path; 
     bool queueRecovered = false; 

     while (!queueRecovered) 
     { 
      try 
      { 
       this.StopListening(queue); 
       queue.Close(); 
       queue.Dispose(); 

       Thread.Sleep(2000); 

       MessageQueue newQueue = this.CreateQueue(queuePath); 

       newQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(this.OnReceiveCompleted); 

       this.StartListening(newQueue); 

       LogUtility.LogInformation(String.Format(CultureInfo.InvariantCulture, "Message queue {0} recovered successfully.", newQueue.QueueName)); 

       queueRecovered = true; 
      } 
      catch (Exception ex) 
      { 
       LogUtility.LogError(String.Format(CultureInfo.InvariantCulture, "The following error occurred while trying to recover queue: {0} error: {1}", queue.QueueName, ex.Message));     
      } 
     }   
    } 

    public void StopListening(MessageQueue queue) 
    { 
     queue.ReceiveCompleted -= new ReceiveCompletedEventHandler(this.OnReceiveCompleted);    
    } 
+0

はオーケーRecoverQueueメソッドのコード – chad

答えて

8

、あなたは、つまりは、あなたのReceiveCompletedイベントをunwiring MessageQueueを配置し、古いMessageQueueを解放する必要がある、などが続いMessageQueueとフックの新しいインスタンスを作成します新しいMessageQueueインスタンスで再びReceiveCompletedイベントまで

また、特定の間隔で新しいインスタンスを作成し、MessageQueue.Receive(TimeSpan)を呼び出し、受信メッセージを待つか、タイムアウトが発生するまで、ポーリング方法を使用できます。この場合、メッセージを処理してMessageQueueインスタンスを破棄し、繰り返しを開始します。

毎回MessageQueueを再作成すると、組み込みの回復が確実に行われます。また、MessageQueueを作成するオーバーヘッドは、基になるキューの内部キャッシングにより最小限に抑えられます。

擬似コード...

while (!notDone)// or use a timer or periodic task of some sort... 
{ 
    try 
    { 
     using (MessageQueue queue = new MessageQueue(queuePath)) 
     { 
      Message message = queue.Receive(TimeSpan.FromMilliseconds(500)); 

      // process message 
     } 
    } 
    catch (MessageQueueException ex) 
    { 
     // handle exceptions 
    } 
} 
+1

を投稿ので、あなたはただ、基本的に言っている:「新しいキューを毎回使用してください」 –

+0

@Bob Horn - はい。内部キャッシュによってオーバーヘッドが低いため、MSMQサービスが再起動されたか、または応答がなくなった問題をより簡単に処理できます。 – Jim

関連する問題