我在其他帖子上看到了此错误,但并非针对这种确切情况。
我有两个使用MessageQueue执行相同操作的类。因此,我将队列的创建和处理抽象为一个助手类。我收到此错误,并且我看不到如何可以多次处理队列。
对象'messageQueue'可以在方法'MsmqHelper.DisposeQueue(MessageQueue)'中多次处置。
在其中一个类中,这是使用队列的方式:
private MessageQueue _messageQueue;
然后,在该类的构造函数中:
this._messageQueue = MsmqHelper.InitializeQueue();
并不是真的很重要,但是为了完整起见,这是使用队列的地方:
this._messageQueue.Send(workflowCreated);
这是Dispose方法:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing == false) { return; }
MsmqHelper.DisposeQueue(this._messageQueue);
}
这是帮助程序类中实际上调用Dispose()的代码:
public static void DisposeQueue(MessageQueue messageQueue)
{
if (messageQueue != null)
{
messageQueue.Close();
messageQueue.Dispose();
messageQueue = null;
}
}
在这种情况下,队列在哪里可能被多次处置?
** 编辑 **
我认为在下面的对话中添加我的评论会很好。这是一个很好的总结,以及可接受的答案:
我想我现在明白了。 messageQueue方法参数与对该对象的原始(this._messageQueue)引用无关。因此,检查messageQueue是否为null,并将其设置为null并没有好处。即使在处置之后,调用方仍可以传递其变量(this._messageQueue)。因此,能够被处置一次以上。
顺便说一句,即使在调用方法中将调用者的变量(this._messageQueue)设置为null也无济于事。该问题仅存在于MsmqHelper.DisposeQueue()中。因此,答案是通过ref传递,或者根本不调用DisposeQueue()并在调用方法中完成所有操作。
**编辑2 **
尝试这个之后,我得到了同样的错误。我根本不明白。
public static void DisposeQueue(ref MessageQueue messageQueue)
{
if (messageQueue == null) { return; }
messageQueue.Close();
messageQueue.Dispose();
messageQueue = null;
}
**编辑3-错误? **
我开始认为这可能是一个错误。如果我评论messageQueue.Dispose(),该错误就会消失。但是,我可以在调用方法中一起调用messageQueue.Close()和messageQueue.Dispose()。去搞清楚。我想我将从调用方法中进行这些相同的调用,或者仅调用Close()或Dispose()而不是两者。
最佳答案
关闭将释放MessageQueue对象的所有资源。参见documentation here。该错误最有可能在CA中生成,因为它看到Close的执行路径也调用了Dispose。
从文档中:
public void ReceiveMessage()
{
// Connect to the a on the local computer.
MessageQueue myQueue = new MessageQueue(".\\myQueue");
// Set the formatter to indicate body contains an Order.
myQueue.Formatter = new XmlMessageFormatter(new Type[]
{typeof(String)});
try
{
// Receive and format the message.
Message myMessage1 = myQueue.Receive();
Message myMessage2 = myQueue.Receive();
}
catch (MessageQueueException)
{
// Handle sources of any MessageQueueException.
}
// Catch other exceptions as necessary.
finally
{
// Free resources.
myQueue.Close();
}
return;
}
关闭显然可以释放资源,但是如果尚未收集资源,则允许组件重新获取它们。最好先打开MessageQueue对象,然后使用它,然后在同一调用中将其关闭,而不要打开它一段时间然后再关闭,因为连接缓存消除了在重复调用中打开MessageQueue的开销。
* 更新*
看来,CA对于成员字段对待CA2202的方式与将一次性对象传递给方法的方式不同,即使该方法是该类专用的。无论如何,根据文档,您只需要调用Close()或Dispose()即可,而不必两者都调用。但是,我建议您更改设计,以便在消息操作范围内全部创建,使用然后关闭MessageQueue对象,如上述文档示例中的示例所示。
关于c# - MessageQueue处理一次以上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9795008/