При создании объекта диспетчера очередей MQ получено сообщение «дескриптор недействителен»

#c# #ibm-mq

#c# #ibm-mq

Вопрос:

Пожалуйста, найдите приведенный ниже код:

 MQEnvironment.Hostname = HostName;
        MQEnvironment.Channel = Channel;

        if (!string.IsNullOrEmpty(SSLKeyRepository))
        {
            MQEnvironment.SSLCipherSpec = SSLCipherSpec;
            MQEnvironment.SSLKeyRepository = SSLKeyRepository;
        }
        if (Port > 0)
            MQEnvironment.Port = Port;

        try
        {
            MQManager = new MQQueueManager(QueueManager);
            try
            {
                MQRequestQueue = MQManager.AccessQueue(QueueNameGet, MQC.MQOO_INPUT_AS_Q_DEF   MQC.MQOO_FAIL_IF_QUIESCING);
                MQResponseQueue = MQManager.AccessQueue(QueueNameGet, MQC.MQOO_OUTPUT   MQC.MQOO_FAIL_IF_QUIESCING);                     
                return true;
            }
            catch (IBM.WMQ.MQException exIBM)
            {
                CloseConnection();
                ErrorCode = exIBM.Reason;
                ErrorDescription = exIBM.Message;
                                }
        }
        catch (IBM.WMQ.MQException exIBM)
        {
            CloseConnection();
            ErrorCode = exIBM.Reason;
            ErrorDescription = exIBM.Message;
        }
        catch (Exception ex)
        {
            CloseConnection();
            ErrorCode = Constants.SYSTEMEXCEPTION;
            ErrorDescription = ex.Message;
        }
        return false;
  

Проблема: я не получаю проблему, когда запускаю ее один или 2-3 раза. Но я получаю проблему, когда он выполняется в цикле несколько раз.
Кроме того, я пытался запустить один и тот же фрагмент кода 10000 раз с сервера IIS, и он был выполнен успешно.

Я получаю проблему только тогда, когда у меня есть этот код в веб-сервисе IIS и этот веб-сервис вызывается несколько раз.

На сервере IIS установлен IBM MQ client 7.5.0.0, и я использую dll той же версии.

ОБНОВИТЬ Описание ошибки:

Сообщение об ошибке дескриптор недействителен
для отслеживания стека в системе.Диагностика.NtProcessManager.GetModuleInfos(идентификатор процесса Int32, логическое значение firstModuleOnly) в системе.Диагностика.Process.get_Modules() в IBM.WMQ.CommonServices.TraceEnvironment() в IBM.WMQ.CommonServices.CreateCommonServices() в IBM.WMQ.CommonServices.TraceEnabled() в IBM.WMQ.MQBase..ctor() в IBM.WMQ.MQManagedObject..ctor()

Комментарии:

1. Можете ли вы опубликовать точный стек исключений? Открывает ли ваше приложение соединение с queue manager каждый раз, когда оно отправляет / получает сообщение? Вы закрываете очереди, которые вы открыли, вызывая метод close, а соединения — вызывая метод disconnect для объекта queue manager?

2. да, он открывает соединение каждый раз при получении / отправке сообщения. и да, я закрываю очереди и queue manager каждый раз после завершения get / put. Итак, код написан следующим образом 1. откройте queue manager 2. получите доступ к очереди 3. получите / поместите сообщение в очередь 4. отключите и закройте QM 5. отключите очереди

3. У меня нет точного стека исключений

4. @Шаши, глядя на profile, кажется, у вас появилось больше идей о том, как работать с компонентом MQSeries, доступным для .NET. как упоминал Роджер ниже, класс MQEnvironment не является потокобезопасным, не так ли??

5. Класс MQEnvironment имеет статический конструктор. Следовательно, он инициализируется только один раз для каждого приложения. Все потоки в приложении будут использовать один и только один экземпляр класса MQEnvironment. Необходима дополнительная диагностическая информация, чтобы понять, что означает ошибка «дескриптор недействителен».

Ответ №1:

Спасибо за предоставление стека вызовов. Проблема, о которой вы упоминаете, очень похожа на ту, которая была исправлена здесь в MQ версии 7.5.0.2. Поскольку вы находитесь на MQ версии 7.5.0.0, я предлагаю вам обновить ваш клиент MQ до последнего уровня, MQ версии 7.5.0.7 и попробовать.

Комментарии:

1. кажется, ваш ответ ближе к проблеме, которую я обнаружил. обновлю вас новыми журналами, если найду таковые

Ответ №2:

Я говорил это здесь много раз, и это применимо как к Java, так и к .NET, класс MQEnvironment НЕ является потокобезопасным. Используя его, вы подставляете себе ногу.

Поместите значения (channel, hostname amp; port #) в хэш-таблицу и передайте хэш-таблицу классу MQQueueManager.

 Hashtable qMgrHT = new Hashtable();
qMgrHT.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);

qMgrHT.Add(MQC.HOST_NAME_PROPERTY, "10.10.10.10");
qMgrHT.Add(MQC.CHANNEL_PROPERTY, "TEST.CHL");
qMgrHT.Add(MQC.PORT_PROPERTY, 1414);

qMgrHT.Add(MQC.USER_ID_PROPERTY, "myUserID");
qMgrHT.Add(MQC.PASSWORD_PROPERTY, "myPwd");

MQQueueManager qMgr = new MQQueueManager(qManager, qMgrHT);
  

Наконец, напишите свой код так, чтобы он поддерживал соединение, а не подключался и отключался снова и снова. Очень, ОЧЕНЬ плохой тон.

Комментарии:

1. Привет, Роджер, спасибо за ответ. Но я не передаю какой-либо параметр вместо имени QM. Я просто удивлен, если переменные MQEnvironment могут быть переданы в QM в качестве параметра, как вы сделали (я новичок в MQSeries) Кроме того, этот конкретный код я поместил в службу, которая размещена на моем сервере IIS, чтобы она была доступна всем. как я могу поддерживать соединение. Я подумал, что было бы неплохо подключить / отключить после его использования.

2. вы хотите сказать, что способ, которым я написал код, является очень плохим форматом? вы можете найти шаги, которые я написал в моем приведенном выше комментарии к Шаши