Существует ли обходной путь, когда системная библиотека ERP не допускает несколько операций асинхронного входа в систему

#c# #.net #quartz.net

#c# #.net #quartz.net

Вопрос:

Я создал приложение, которое отправляет счета получателям из ERP-системы под названием Comarch Optima. Для печати вложения я использую встроенные функции этой системы (с COM-объектами). К сожалению, это не позволяет вам входить в систему из двух разных потоков. Я использовал Quartz.net (версия 3.0.7) в качестве таймера и создал две задачи — первую каждые 5 минут и вторую в 12:15. Оба будут запускаться одновременно.

Я получаю сообщение об ошибке:

OLE database multi-step operation generated errors. Check all OLE database status values. No action was taken.

Я спросил центр поддержки ERP, как решить эту проблему. Я получил ответ:

It is not possible to log in several times simultaneously within one process. Such operations must be performed synchronously. If one thread logs in, another thread cannot log in, it must wait for the first thread to complete all operations and log off.

Могу ли я что-нибудь с этим сделать? Должен ли я заменить Quartz на что-то другое?

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

1. Если вы выполняете одно и то же задание по нескольким расписаниям, простым решением является добавление [DisallowConcurrentExecution] атрибута. Если это разные задания, и они выполняются не слишком долго, обходной путь заключается в том, чтобы заставить их захватить общую блокировку (например, a SemaphoreSlim ), чтобы они не выполнялись одновременно. Если это разные задания и они выполняются долго, вам может потребоваться разобраться с пользовательским планировщиком. Если вам вообще не нужен параллелизм (для любого задания), установка глобального quartz.threadPool.maxConcurrency = 1 (in quartz.config ) полностью отключит его.

2. @JeroenMostert но мне все равно нужно запустить вторую задачу. [DisallowConcurrentExecution] не создает очередь, поэтому, если у меня есть задача, которая выполняется только один раз в день, она никогда не будет выполнена. Я должен иметь возможность запускать гораздо больше задач одновременно. Это всего лишь пример.

3.Это только первая альтернатива, которую я предоставил. Вы можете запускать столько задач, сколько захотите, но только одна может использовать ERP-систему одновременно, согласно полученной вами обратной связи. Это означает, что так или иначе вы должны обеспечить эксклюзивный доступ. Одним из способов сделать это является перенос доступа к соединению во всех заданиях ( SemaphoreSlim например, со статическим) ( maxConcurrency = 1 кстати, позволяет запускать задачи последовательно). Если вам нужен настоящий параллелизм даже для доступа к ERP, это должен исправить ваш поставщик, а не вы.

4. Похоже, решения нет. Каждое вмешательство в поток, в котором создаются объекты ERP-системы, получает исключение с нулевой ссылкой. Login() метод требует передачи ModuleCollection объекта с выбранными модулями. Я получаю исключение ModuleCollection mc = new ModuleCollection() , которое не вызывает никаких ощущений… Stacktrace также заканчивается на этом. Я делаю что-то не так?

5. Поскольку это COM, вы можете столкнуться с проблемами с квартирами (в основном, с тем, что COM вызывает потоковую обработку), когда вам требуется использовать COM-объекты только в потоке, который их создал, и, кроме того, этот поток должен иметь правильный режим квартиры, чтобы иметь возможность использовать эти объекты. Если это так, вам лучше вообще забыть о потоковой передаче. Используйте очередь приоритетов для планирования действий (с некоторыми Threading.Timer s для ввода событий) и запускайте все из одного потока. Теоретически, вы можете написать для этого пользовательский планировщик в Quartz, который будет это делать. На практике я сомневаюсь, что оно того стоит.