2012-04-26 39 views
9

Chúng tôi có một dịch vụ nhận tin nhắn từ hàng đợi tin nhắn n. Tuy nhiên, nếu dịch vụ xếp hàng thư được khởi động lại, dịch vụ truy xuất thư sẽ ngừng nhận thư ngay cả sau khi dịch vụ xếp hàng thư đã khởi động lại thành công.Dịch vụ không nhận được tin nhắn sau khi dịch vụ Xếp hàng Tin nhắn khởi động lại

Tôi đã cố gắng nắm bắt đặc biệt MessageQueueException được đưa vào dịch vụ truy xuất thư và gọi lại phương thức BeginReceive của hàng đợi một lần nữa. Tuy nhiên, trong 2 giây hoặc lâu hơn, nó sẽ nhận dịch vụ xếp hàng thư để khởi động lại, tôi nhận được khoảng 1875 trường hợp ngoại lệ và sau đó dịch vụ ngừng hoạt động khi một MessageQueueException khác được ném trong phương thức StartListening của chúng tôi.

Có cách nào thanh lịch để khôi phục dịch vụ thư xếp hàng không?

private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e) 
    { 
     MessageQueue queue = (MessageQueue)sender; 

     try 
     { 
      Message message = queue.EndReceive(e.AsyncResult); 

      this.StartListening(queue); 

      if (this.MessageReceived != null) 
       this.MessageReceived(this, new MessageReceivedEventArgs(message)); 
     } 
     catch (MessageQueueException) 
     { 
      LogUtility.LogError(String.Format(CultureInfo.InvariantCulture, StringResource.LogMessage_QueueManager_MessageQueueException, queue.MachineName, queue.QueueName, queue.Path)); 
      this.StartListening(queue); 
     }    
    } 

    public void StartListening(MessageQueue queue) 
    { 
     queue.BeginReceive(); 
    } 

Tôi cần xử lý vấn đề vòng lặp vô hạn mà nguyên nhân này và làm sạch nó một chút nhưng bạn có ý tưởng.

Khi MessageQueueException xảy ra, hãy gọi phương thức 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

văn mã phương pháp RecoverQueue – chad

Trả lời

8

Khi nhận được ngoại lệ mà là kết quả của việc khởi động lại dịch vụ, bạn phải giải phóng cũ MessageQueue, tức là unwiring kiện ReceiveCompleted của bạn, xử lý các MessageQueue, vv Sau đó, tạo một đối tượng mới của MessageQueue và móc lên đến sự kiện ReceiveCompleted một lần nữa trên phiên bản MessageQueue mới.

Ngoài ra, bạn có thể sử dụng phương pháp bỏ phiếu tạo phiên bản mới trong một khoảng thời gian nhất định, gọi MessageQueue.Receive(TimeSpan), sẽ đợi thư đến hoặc cho đến khi hết thời gian chờ. Trong trường hợp này, bạn xử lý tin nhắn và phá hủy phiên bản MessageQueue và bắt đầu lặp lại lần nữa.

Bằng cách tạo lại MessageQueue mỗi lần, bạn đảm bảo được khôi phục được tích hợp sẵn. Ngoài ra, chi phí của việc tạo ra MessageQueue là tối thiểu do bộ nhớ đệm nội bộ của hàng đợi nằm bên dưới.

Pseudo-code ...

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

Được rồi, vì vậy bạn chỉ là về cơ bản nói: "Sử dụng một hàng đợi mới mỗi khi" –

+0

@Bob Horn - Có. Bởi vì chi phí thấp do bộ nhớ đệm bên trong, nó giúp dễ dàng xử lý các vấn đề mà dịch vụ MSMQ được khởi động lại hoặc ngược lại không phản hồi. – Jim

Các vấn đề liên quan