6

リモート サーバーで MSMQ を使用して保留中の電子メールをキューに入れる Web サイトがあります。メッセージをキューに書き込んでから、キューで dispose を呼び出すことができます。キューは引き続きメッセージを受け取りますが、しばらくして GC が来てクリーンアップを試み、IIS がクラッシュします。これは、イベント ログに表示されるものです。

例外: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このコードの周りには a があり、決してcatchブロックに入らないことがわかっています。これは、アプリケーション全体が .NET 3.5 から .NET 4.0 にアップグレードされたときに発生したと考え始めています。ただし、散発的に発生するようになりましたが、今ではキューにメッセージを書き込むたびに発生します。

編集 2

ここにコードがありますBuildQueue

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

1 に答える 1

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();
    }
}
于 2013-01-11T14:53:07.987 に答える