MSMQ に関するエラーが発生しましたが、オンラインで解決策が見つかりません。スタックトレースは次のとおりです。
System.Messaging.MessageQueueException (0x80004005): An invalid handle was passed to the function.
at System.Messaging.MessageQueue.ReceiveCurrent(TimeSpan timeout, Int32 action, CursorHandle cursor, MessagePropertyFilter filter, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
at System.Messaging.MessageQueue.Peek(TimeSpan timeout, Cursor cursor, PeekAction action)
at Utility.Msmq.MsmqManager.PeekWithoutTimeout(Cursor cursor, PeekAction action)
at Utility.Msmq.MsmqManager.SearchMessages(List`1 labels)
キューは、次のコードを使用して初期化されます。
var queuePath = isIp
? (machineName == "127.0.0.1"
? string.Format(@".\Private$\{0}", queueName)
: string.Format("FormatName:Direct=OS:{0}\\private$\\{1}", machineName,
queueName))
: string.Format("FormatName:Direct=TCP:{0}\\private$\\{1}", machineName, queueName);
try
{
_queue = MessageQueue.Exists(queuePath)
? new MessageQueue(queuePath)
: MessageQueue.Create(queuePath, true);
_queue.MessageReadPropertyFilter.Priority = true;
_queue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
}
catch(MessageQueueException)
{
// Concurrent threads on a new company will try to create the queue at once, which throws an error
// If this happens, wait 100ms, then check if queue was created by some other thread, and return it.
while (!MessageQueue.Exists(queuePath))
{
Thread.Sleep(100);
}
_queue = new MessageQueue(queuePath);
}
これは、msmq でピークを実行するコードです。
private Message PeekWithoutTimeout(Cursor cursor, PeekAction action)
{
Message ret = null;
try
{
ret = _queue.Peek(new TimeSpan(1), cursor, action);
}
catch (MessageQueueException mqe)
{
if (mqe.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
{
throw;
}
}
catch (Exception generalException)
{
Loggers.CreateBillLogger.Error(generalException.Message, generalException);
throw generalException;
}
return ret;
}
public List<Message> SearchMessages(List<string> labels)
{
var count = 0;
var cursor = _queue.CreateCursor();
var messages = new List<Message>();
var message = PeekWithoutTimeout(cursor, PeekAction.Current);
if (message != null)
{
if (labels.Contains(message.Label))
{
messages.Add(message);
}
do
{
message = PeekWithoutTimeout(cursor, PeekAction.Next);
if (message != null && labels.Contains(message.Label))
{
messages.Add(message);
}
} while (message != null);
}
return messages;
}
PS注意すべきことの1つは、このコードはBackgroundWorkersを使用してマルチスレッド環境で実行され、2つ以上のスレッドが一度にキューを作成しようとする大きな変更があり、同時作成につながることです。この問題は、catch ブランチで解決されました。
私が間違っていることはありますか?ありがとう !