C# 最后处理WebSphereMQ连接
我在.Net代码中连接到IBM Websphere MQ服务器,我希望确保在使用finally时遵循最佳实践 我现在有下面的代码块,我相信可以修改它,使其在finally子句中有结束部分。对吗?我在应用程序的调用部分捕获错误C# 最后处理WebSphereMQ连接,c#,ibm-mq,C#,Ibm Mq,我在.Net代码中连接到IBM Websphere MQ服务器,我希望确保在使用finally时遵循最佳实践 我现在有下面的代码块,我相信可以修改它,使其在finally子句中有结束部分。对吗?我在应用程序的调用部分捕获错误 Hashtable properties = new Hashtable(); properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT); properties.Add
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();
}
编辑:雷南提出了一个很好的建议。我不认为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;
}
编辑:在阅读了雷南的建议后,我做了一些研究,发现如下。听起来他们真的把它变成了一次性的
那很好
CLR保证调用finally块,但在某些非常罕见的边缘情况下除外,这些情况下IIRC是内部CLR错误,例如调用FailFast或ExecutionEngineException。从try中删除它就是删除冗余代码。你说得对。即使try块中的代码返回异常,finally子句也将执行 如果连接实现了IDisposable,您也可以使用using构造,它应该实现IDisposable
using(qmgr){
//do stuff
}
首先,应用程序不需要知道队列的深度。应用程序应处理队列中的所有消息,直到队列为空 第二,不要使用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);
}
}
“qmgr”从何而来?嗨,John,我遗漏了定义qmgraded方法的代码的一部分。John,如果qmgr!=null&&qmfr.IsOPen,因为它避免了在tryThanks Conrad中qmgr为null时引发两个异常…我将对此进行研究。使用要求qmgr实现IDisposable。是吗?