2009-12-16 37 views
14

Tôi nhận được ngoại lệ khi thực thi mã sau. Bất kỳ ý tưởng gì là sai?Không thể xác định xem hàng đợi có tên định dạng được chỉ định có tồn tại hay không

string queueName = "FormatName:Direct=TCP:1.1.1.1\\Private$\\test"; 
MessageQueue queue; 

if (MessageQueue.Exists(queueName)) 
    queue = new System.Messaging.MessageQueue(queueName); 
else 
    queue = MessageQueue.Create(queueName); 
queue.Send(sWriter.ToString()); 

Edit: Dưới đây là thông điệp ngoại lệ và dòng đầu tiên của stacktrace

Không thể xác định liệu một hàng đợi với tên định dạng cụ thể tồn tại.
tại System.Messaging.MessageQueue.Exists (Đường dẫn chuỗi)

Nó hoạt động cho hàng đợi cục bộ bằng cách này.

+1

cung cấp thông báo ngoại lệ, vui lòng –

Trả lời

35

Từ mẫu của bạn, có vẻ như bạn đang cố gắng để kiểm tra xem một hàng đợi tin xa tồn tại, nhưng là tài liệu MessageQueue.Exists nói:

Tồn tại không thể được gọi để xác minh tồn tại của một cá nhân từ xa xếp hàng.

Cố gắng làm như vậy sẽ tạo ra InvalidOperationException.


Nếu bạn thực sự cần thông tin này cho công việc của bạn, bạn có thể sử dụng phương pháp MessageQueue. GetPrivateQueuesByMachine và lặp kết quả để tìm một trận đấu. Nếu bạn làm như vậy, tôi khuyên bạn nên đọc Are Remote MSMQ Queues Reliable?, thảo luận về cách tiếp cận này ở một số độ sâu.

This post from the excellent "MSMQ from the plumber's mate" blog đề xuất một giải pháp thay thế khác: thậm chí không kiểm tra xem hàng đợi của bạn có tồn tại hay không, "mà thay vào đó xử lý không phân phối thư thì hóa ra hàng đợi không tồn tại." (Bạn sẽ cần phải theo dõi hàng đợi điều hành và/hoặc hàng đợi thư chết, nhưng có lẽ bạn nên làm điều đó anyway.)

4

Hãy thử này ...

public static bool IsQueueAvailable(string queueName) 
    { 
     var queue = new MessageQueue(queueName); 
     try 
     { 
      queue.Peek(new TimeSpan(0, 0, 5)); 
      return true; 
     } 
     catch (MessageQueueException ex) 
     { 
      return ex.Message.StartsWith("Timeout"); 
     } 
    } 

Nếu hàng đợi không tồn tại hoặc nếu tài khoản đang chạy ứng dụng không có đủ quyền để truy cập, thông báo ngoại lệ sẽ nêu rõ như vậy.

VÀ, điều này sẽ hoạt động với cả FormatName và đường dẫn hàng đợi thông thường.

+1

Khi thử nghiệm, tôi đã hết thời gian chờ khi Hàng đợi trống. – NealWalters

+0

@NealWalters kiểm tra câu trả lời kết hợp của tôi: http://stackoverflow.com/a/34633405/1306012 –

2

Câu trả lời ở trên với việc kiểm tra thông báo ngoại lệ sẽ hoạt động trên các hệ thống tăng ngoại lệ tiếng Anh. Hệ thống của tôi làm tăng ngoại lệ của Hà Lan. Tôi nhận được "De thời gian ra voor de gevraagde bewerking là verstreken." Vì vậy, nó không phải là một giải pháp rất mạnh mẽ Ngoại lệ có một tài sản MessageQueueErrorCode nên được sử dụng để kiểm tra xem có hay không một IOTimeout xảy ra.

Vì vậy, nó là tốt hơn để sử dụng

return (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout); 

thay vì:

return ex.Message.StartsWith("Timeout"); 
0

Bạn không thể sử dụng Tồn tại phương pháp trên một hàng đợi từ xa, vì vậy bạn phải mạo danh người dùng trên máy từ xa:

//usings 
using System; 
using System.Messaging; 
using System.Runtime.InteropServices; 
using System.Security; 
using System.Security.Principal; 

//Declaring the advapi32.dll 
[DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool LogonUser(
      string lpszUsername, 
      string lpszDomain, 
      string lpszPassword, 
      int dwLogonType, 
      int dwLogonProvider, 
      out IntPtr phToken); 

private void IterateRemoteMQ() 
    { 
     IntPtr userToken = IntPtr.Zero; 

     bool success = LogonUser(
      "REMOTE_USERNAME", //Username on the remote machine 
      ".", //Domain, if not using AD, Leave it at "." 
      "PASSWORD", //Password for the username on the remote machine 
      9, //Means we're using new credentials, otherwise it will try to impersonate a local user 
      0, 
      out userToken); 

     if (!success) 
     { 
      throw new SecurityException("Logon user failed"); 
     } 
     //Go through each queue to see if yours exists, or do some operation on that queue. 
     using (WindowsIdentity.Impersonate(userToken)) 
     { 
      MessageQueue[] Queues = MessageQueue.GetPrivateQueuesByMachine("192.168.1.10"); 
      foreach (MessageQueue mq in Queues) 
      { 
       string MSMQ_Name = mq.QueueName; 
      } 
     } 
1

Tôi đã kết thúc với câu trả lời từ Svix, Erwin van DijkJoseph Daigle được kết hợp. Ngoài ra, tôi đã kiểm tra ArgumentException:

/// <summary> 
    /// Checks if a (remote) Microsoft Message Queue is available 
    /// </summary> 
    /// <param name="queueName">The name of the Message Queue.</param> 
    /// <returns>Returns true if the queue is available otherwise false.</returns> 
    public static bool IsQueueAvailable(string queueName) 
    { 
     MessageQueue queue; 
     try 
     { 
      queue = new MessageQueue(queueName); 
      queue.Peek(new TimeSpan(0, 0, 5)); // wait max. 5 sec. to recieve first message from queue (reduce if necessary) 
      return true; 
     } 
     catch (Exception ex) 
     { 
      if(ex is ArgumentException) 
      { // the provided queue name is wrong. 
       return false; 
      } 
      else if (ex is MessageQueueException) 
      { // if message queue exception occurs either the queue is avialable but without entries (check for peek timeout) or the queue does not exist or you don't have access. 
       return (((MessageQueueException)ex).MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout); 
      } 
      // any other error occurred. 
      return false; 
     } 
    } 
Các vấn đề liên quan