最后处理 WebSphere MQ 连接
本文关键字:连接 MQ WebSphere 后处理 最后 | 更新日期: 2023-09-27 18:31:04
我正在用我的 .Net 代码连接到 IBM Websphere MQ 服务器,我想确保在使用"final"时遵循最佳实践。
我目前有以下代码块,我相信可以对其进行修改,使其仅在 finally 子句中具有关闭部分。 这是对的吗?(我在应用程序的调用部分捕获错误)。
Hashtable properties = new Hashtable();
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
properties.Add(MQC.CHANNEL_PROPERTY, channel);
properties.Add(MQC.HOST_NAME_PROPERTY, host);
properties.Add(MQC.PORT_PROPERTY, port);
MQQueueManager qmgr = new MQQueueManager(queueManager, properties);
try
{
var queueDepth = qmgr.AccessQueue(userQueue,
MQC.MQOO_INPUT_AS_Q_DEF +
MQC.MQOO_FAIL_IF_QUIESCING +
MQC.MQOO_INQUIRE).CurrentDepth;
if (qmgr.IsOpen)
qmgr.Close();
return queueDepth;
}
finally
{
if (qmgr.IsOpen)
qmgr.Close();
}
现在是这个
Hashtable properties = new Hashtable();
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
properties.Add(MQC.CHANNEL_PROPERTY, channel);
properties.Add(MQC.HOST_NAME_PROPERTY, host);
properties.Add(MQC.PORT_PROPERTY, port);
MQQueueManager qmgr = new MQQueueManager(queueManager, properties);
try
{
var queueDepth = qmgr.AccessQueue(userQueue,
MQC.MQOO_INPUT_AS_Q_DEF +
MQC.MQOO_FAIL_IF_QUIESCING +
MQC.MQOO_INQUIRE).CurrentDepth;
return queueDepth;
}
finally
{
if (qmgr.IsOpen)
qmgr.Close();
}
编辑:Renan提出了一个很好的建议。 我不认为MQQueueManger是一次性的。 听起来我可能会这样做:
using(MQQueueManager qmgr = new MQQueueManager(queueManager, properties))
{
var queueDepth = qmgr.AccessQueue(userQueue,
MQC.MQOO_INPUT_AS_Q_DEF +
MQC.MQOO_FAIL_IF_QUIESCING +
MQC.MQOO_INQUIRE).CurrentDepth;
return queueDepth;
}
编辑:在阅读Renan的建议后,我做了一些研究,发现了以下内容。 听起来他们确实使它成为一次性的。
MQ.Net
你是对的。finally 子句将执行,即使 try 块中的代码返回异常。
您还可以对连接使用"using"构造(如果它实现了 IDisposable,它应该实现)。
using(qmgr){
//do stuff
}
这很好。
CLR 保证要调用finally
块(除了一些非常非常罕见的边缘情况,IIRC 是内部 CLR 错误,例如调用FailFast
或ExecutingEngineException
)。通过将其从try
中删除,您将删除冗余代码。
首先,应用程序没有正当理由需要知道队列的深度。 应用程序应处理队列中的所有消息,直到它为空。
其次,不要使用 IsOpen 方法,因为它们不能像您期望的那样工作。 IsOpen 方法实际上并不检查队列句柄是否打开 - 它只检查内部标志。 因此,不要使用它。
第三,您不会关闭队列管理器对象,而是断开与队列管理器的连接。
第四,当连接到队列管理器时,该语句需要位于 try/catch 中,因为如果连接失败,它将抛出 MQException。
下面是一个更好的代码布局,它将捕获和处理错误:
MQQueueManager qMgr = null;
MQQueue queue = null;
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING + MQC.MQOO_INQUIRE;
try
{
qMgr = new MQQueueManager(qMgrName);
System.Console.Out.WriteLine("Successfully connected to " + qMgrName);
queue = qMgr.AccessQueue(qName, openOptions, null, null, null);
System.Console.Out.WriteLine("Successfully opened " + qName);
System.Console.Out.WriteLine("Current queue depth is " + queue.CurrentDepth);
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("Exception CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
}
catch (System.IO.IOException ioex)
{
System.Console.Out.WriteLine("Exception ioex=" + ioex);
}
finally
{
try
{
if (queue !=null)
{
queue.Close();
System.Console.Out.WriteLine("Successfully closed " + qName);
}
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("Exception on close CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
}
try
{
if (qMgr !=null)
{
qMgr.Disconnect();
System.Console.Out.WriteLine("Disconnected from " + qMgrName);
}
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("Exception on disconnect CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
}
}