2012-07-05 60 views
0

在C#ASP.NET 3.5 Web应用程序在Windows消息队列的所有消息,我在一段时间出现以下错误一次:零星的错误而获得Windows Server 2003上运行

"Object reference not set to an instance of an object.: at System.Messaging.Interop.MessagePropertyVariants.Unlock() 
    at System.Messaging.Message.Unlock() 
    at System.Messaging.MessageQueue.ReceiveCurrent(TimeSpan timeout, Int32 action, CursorHandle cursor, MessagePropertyFilter filter, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType) 
    at System.Messaging.MessageEnumerator.get_Current() 
    at System.Messaging.MessageQueue.GetAllMessages()". 

的代码,将引发此行错误是:

Message[] msgs = Global.getOutputQueue(mode).GetAllMessages(); 

其中Global.getOutputQueue(mode)给我希望从中获取邮件的消息队列。

更新:

Global.getPool(mode).WaitOne(); 
commonClass.log(-1, "Acquired pool: " + mode, "Report ID: " + unique_report_id); 
      ............../* some code / .............. lock(getLock(mode)) { bool yet_to_get = true; int num_retry = 0; do { try { msgs = Global.getOutputQueue(mode).GetAllMessages(); yet_to_get = false; } catch { Global.setOutputQueue(mode); msgs = Global.getOutputQueue(mode).GetAllMessages(); yet_to_get = false; } ++num_retry; } while (yet_to_get && num_retry < 2); } ... / some code*/ 
.... 
finally 
      { 
       commonClass.log(-1, "Released pool: " + mode, "Report ID: " + unique_report_id); 
       Global.getPool(mode).Release(); 
      } 

回答

1

你的描述,建议this thread一个时间问题。我很少创建MessageQueue对象(可能只有一次),并且Global.getOutputQueue(mode)返回一个缓存版本,似乎可能会解决此问题。

编辑:进一步的细节表明你有相反的问题。我建议封装对消息队列的访问,捕获此异常并在发生异常时重新创建队列。因此,像这样的东西替代呼叫Global.getOutputQueue(模式).GetAllMessages():

public void getAllOutputQueueMessages() 
{ 
    try 
    { 
     return queue_.GetAllMessages(); 
    } 
    catch (Exception) 
    { 
     queue_ = OpenQueue(); 
     return queue_.GetAllMessages(); 
    } 
} 

你会发现我没有保护你的mode功能,但你的想法。当然,你必须复制这个模式来进行你对队列的其他调用,但仅限于你所做的(不是整个队列接口)。

+0

Thanks tallseth。 MessageQueue对象已经在Application_Start(Object sender,EventArgs e)中创建。 Global.getOutputQueue(mode)方法只返回它。我错过了什么吗?谢谢。 public static MessageQueue getOutputQueue(char mode) { return(mode =='d')? outputQd:outputQw; } – engg 2012-07-05 22:22:09

+0

听起来像你可能会遇到相反的问题,一个陈旧的队列处理。如果可能的话,不要将队列返回给调用代码,而是代理您需要的队列上的方法。然后捕获此异常,并通过重新创建队列来处理它,然后再次尝试。确保不要递解,但如果事情发生错误,你不想要无限循环。 – tallseth 2012-07-05 22:30:35

1

这是一个古老的线程,但谷歌带我到这里,所以我会补充我的发现。

我同意用户:tallseth,这是一个时间问题。

消息队列创建后,它不是即时可用的。

 try 
     { 
      return _queue.GetAllMessages().Length; 
     } 
     catch (Exception) 
     { 
      System.Threading.Thread.Sleep(4000); 
      return _queue.GetAllMessages().Length; 
     } 

尝试添加一个暂停,如果您在访问已知创建的队列时发现异常。

与此相关的

_logQueuePath = logQueuePath.StartsWith(@".\") ? logQueuePath : @".\" + logQueuePath; 
_queue = new MessageQueue(_logQueuePath); 
MessageQueue.Create(_logQueuePath); 
bool exists = MessageQueue.Exists(_logQueuePath); 

运行MessageQueue.Exists(串nameofQ);方法创建队列后立即返回false。调用代码时要小心,例如:

 public void CreateQueue() 
    { 
     if (!MessageQueue.Exists(_logQueuePath)) 
     { 
      MessageQueue.Create(_logQueuePath); 
     } 
    } 

因为它很可能会抛出异常,说明你正在试图创建队列存在。

-edit(对不起,我没有相关的链接,这个新的信息)

,我读了一个新创建的MessageQueue将返回false上MessageQueue.Exists(QueuePath),直到它已收到至少一信息。

保持这一点以及我之前提到的要点已经使我的代码可靠运行。

+0

谢谢Tessi。我的代码最近一直稳定。 – engg 2014-05-23 13:27:23

相关问题