2013-01-02 13 views
6

我有一個網站在遠程服務器上使用MSMQ排隊掛起的電子郵件。我能夠將消息寫入隊列,然後在隊列上調用dispose。隊列仍然收到消息,但是有一段時間後,GC出現並嘗試清理並導致IIS崩潰。這是我看到在事件日誌中:MSMQ CreateCursor NullReferenceException

例外:System.NullReferenceException

消息:對象引用未設置到對象的實例。

堆棧跟蹤:at System.Messaging.Cursor.Finalize()

此代碼已經多年運行良好,但它只是最近開始演戲了。我重新啓動了所有服務器進行故障排除,但這並沒有幫助。

編輯1

這裏是正在發送的消息的代碼。 QueueFactory只是一個創建一個MessageQueue鎖的單身人士。

using (System.Messaging.MessageQueue queue 
    = QueueFactory.Instance.BuildQueue(this.Path)) 
{ 
    System.Messaging.Message message = new System.Messaging.Message 
    { 
     Body = body, 
     Formatter = new BinaryMessageFormatter(), 
     TimeToBeReceived = this.ExpirationMinutes 
    }; 

    queue.Send(message, label); 
} 

周圍有此代碼try-catch,我知道它永遠不會使它進入catch塊。我開始認爲這是在整個應用程序從.NET 3.5升級到.NET 4.0時引起的。然而,它開始偶爾發生,但現在每次我向隊列寫入消息時都會發生。

編輯2

這裏是BuildQueue

lock (lockHandler) 
{ 
    return new System.Messaging.MessageQueue(queuePath); 
} 
+0

可能要添加更多的信息,如...完整的堆棧跟蹤,排隊和處理隊列的源代碼。看起來好像你有垃圾回收,你不需要自己處理垃圾回收。 –

+0

這是整個堆棧跟蹤,我只是簡單地調用MessageQueue對象上的Send,該對象已在使用塊中構建。我認爲這對於GC處理的處置對象來說是非常標準的。 – goalie7960

+0

因此,排隊消息的服務器或正在讀取消息的遠程服務器上發生異常嗎?來自MSDN「讀取隊列消息時,Cursor用於維護MessageQueue中的特定位置。」 http://msdn.microsoft.com/en-us/library/system.messaging.cursor.aspx –

回答

0

代碼嘗試使用交易:

using (System.Messaging.MessageQueue queue 
    = QueueFactory.Instance.BuildQueue(this.Path)) 
{ 
    System.Messaging.Message message = new System.Messaging.Message 
    { 
     Body = body, 
     Formatter = new BinaryMessageFormatter(), 
     TimeToBeReceived = this.ExpirationMinutes 
    }; 

    MessageQueueTransaction transaction = new MessageQueueTransaction(); 

    try 
    { 
     transaction.Begin(); 
     queue.Send(message, label, transaction); 
     transaction.Commit(); 
    } 
    catch(System.Exception e) 
    { 
     transaction.Abort(); 
     throw e; 
    } 
    finally 
    { 
     transaction.Dispose(); 
    } 
} 
+0

這可能會也可能不會,但我想知道爲什麼突然發生這種情況。 – goalie7960

+0

事務有可能會捕獲無事務流程沒有的錯誤。 – ic3b3rg

+0

消息隊列應該設置爲事務性或非事務性 - 如果它們是非事務性的,那麼如果您嘗試在其上打開事務,則代碼將失敗。您可以查看計算機管理中的隊列以查看它是否是事務性的。 – penguat