|
10.04.2015, 15:07 | #1 |
Участник
|
Как передать для Thread временные таблицы?
Ax2009. Как передать в новую нить (Thred) содержимое временной таблицы?
У меня пока единственная идея - это конвертация содержимого таблицы в нечто более примитивное. Например, в контейнер через buf2con() / con2buf(). Но, может есть варианты без конвертации? PS: GlobalCache - не работает, поскольку в новом Thread получаю чистый (новый) GlobalCache Пока работаю так: X++: // Вызов Thread void run() { Thread thread; Container conHeader; ; while select headerData { conHeader += [global::buf2con(headerData)]; } thread = new Thread(); thread.setInputParm([conHeader]); thread.removeOnComplete(true); thread.run(classnum(MyClass), staticmethodstr(MyClass, runThread)); thread.waitUntilSignaled(); infolog.import(thread.getOutputParm()); } // Обработка static void runThread(Thread _thread) { container packedArgs; container conHeader; container conValue; int nextI; MyClass report; TmpTable headerData; ; report = new MyClass(); packedArgs = _thread.getInputParm(); conHeader = conPeek(packedArgs, 1); for (nextI = 1; nextI <= conLen(conHeader); nextI++) { conValue = conPeek(conHeader, nextI); global::con2buf(conValue, headerData); headerData.insert(); } // Метод через setTmpData() актуализирует временную таблицу в контексте класса report.setHeaderData(headerData); // Выполнение report.run(); _thread.setOutputParm(infolog.copy(1,infolog.num())); }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
10.04.2015, 15:27 | #2 |
Участник
|
Вот тут предлагают Set.
|
|
|
За это сообщение автора поблагодарили: Владимир Максимов (2). |
10.04.2015, 15:32 | #3 |
NavAx
|
А почему не через параметры? Если все нити работают в одно время, то не вижу проблемы. Нужно проинициализировать курсор временной таблицы в самом начале (лучше на сервере) и его использовать.
Инициализировать так: X++: server static TmpTableName initTmpTableName() { TmpTableName tmpTableName; ; tmpTableName.clear(); tmpTableName.insert(); tmpTableName.delete(); return tmpTableName; } Последний раз редактировалось raz; 10.04.2015 в 15:36. |
|
10.04.2015, 15:38 | #4 |
Участник
|
Если не секрет, зачем вам thread ?
Если распараллеливаете задачу на потоки для ускорения, то лучше уж пакеты сделать с помощниками как в закрытии склада. |
|
10.04.2015, 17:19 | #5 |
Участник
|
Цитата:
Сообщение от Stitch_MS
Вот тут предлагают Set.
Потому, что для Thread передать как параметр временную таблицу не получится. Передается только "голая" структура. Без данных. Ну, или я "не умею их готовить" Можете сделать пример с использованием Thread, чтобы это работало? "Где бы, что ни говорили, все одно сведет на баб" (с) Ответить-то я могу, это даже не секрет, но практика показывает, что после ответа на вопрос "зачем" обсуждение основного вопроса прекращается, и начинаются советы как делать по другому, чего не хотелось бы... Вот об этом я и говорю... Для особо упорных - нет. Речь не идет об ускорении... Использование Thread необходимо, чтобы избежать некоторых ошибок в процессе исполнения. Т.е. отказаться от Thread можно, но сложно...
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
10.04.2015, 17:46 | #6 |
NavAx
|
|
|
10.04.2015, 18:16 | #7 |
Участник
|
Потому, что это временные данные Нужны только на время работы класса. По окончании работы класса удаляются.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
10.04.2015, 19:06 | #8 |
Участник
|
|
|
10.04.2015, 19:05 | #9 |
Участник
|
Если вы захотите когда нить свою обработку засунуть в пакет, то обнаружите что thread в пакетном режиме не работают. И это будет облом.
|
|
13.04.2015, 08:37 | #10 |
Участник
|
Не думаю, что это в принципе получится
Для каждого нового экземпляра Thread создается своя куча (убедиться в этом можно при помощи класса HeapCheck, созданного внутри потока), со своим набором объектов и курсоров По-этому, в принципе нельзя получить ссылку на объект из другого потока Скорее всего, таким образом добиваются безопасности потоков, поскольку в языке нет базовый классов/функций, позволяющих выполнять параллельный доступ
__________________
Axapta v.3.0 sp5 kr2 Последний раз редактировалось AndyD; 13.04.2015 в 08:39. |
|
|
За это сообщение автора поблагодарили: Владимир Максимов (2), Logger (2), Kabardian (4). |
13.04.2015, 16:44 | #11 |
Британский учённый
|
Есть хороший пост на MSDN Threading in Dynamics AX.
__________________
Людям физического труда для восстановления своих сил нужен 7-8 часовой ночной сон. Людям умственного труда нужно спать часов 9-10. Ну а программистов будить нельзя вообще. |
|
|
За это сообщение автора поблагодарили: AlGol (1), virtuoso (1). |
01.06.2015, 21:27 | #12 |
Участник
|
Цитата:
Сообщение от AndyD
Не думаю, что это в принципе получится
Для каждого нового экземпляра Thread создается своя куча (убедиться в этом можно при помощи класса HeapCheck, созданного внутри потока), со своим набором объектов и курсоров По-этому, в принципе нельзя получить ссылку на объект из другого потока Скорее всего, таким образом добиваются безопасности потоков, поскольку в языке нет базовый классов/функций, позволяющих выполнять параллельный доступ Зависает Thread.run() Последний раз редактировалось Logger; 01.06.2015 в 21:30. |
|
20.04.2015, 09:56 | #13 |
Участник
|
Возможно в ax 2012. В 2009 не думаю что получится передать напрямую.
В 2012 есть метод Common.getPhysicalTableName() и если таблица TempDB то к ней можно достучатся напрямую через SQL (используется в change tracking в R3. см. метод \Classes\RetailCDXChangeTracking\runChangeTracking_table) Если очень хочется, можно самому создавать временную таблицу на SQL (из X++), передавать ее имя в Thread, написать обертку вокруг всего этого ....
__________________
AxAssist 2012 - Productivity Tool for Dynamics AX 2012/2009/4.0/3.0 |
|
20.04.2015, 11:34 | #14 |
Участник
|
Цитата:
Временная таблица MS SQL "живет" в рамках созданного соединения. В терминах Axapta: в рамках объекта Connection (или ODBCConnection или UserConnection). Но передать любой объект в новый Thread - невозможно! Следовательно, и про объект Connection можно забыть... Нет, можно, конечно, делать глобальную временную таблицу, но это уже мало чем отличается от постоянной таблицы со всеми сопутствующими проблемами... Или Thread всегда (?) работает в рамках того же самого соединения, не создавая нового?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
20.04.2015, 10:36 | #15 |
Участник
|
Не смешивайте, пожалуйста)
Для InMemory и в 2012 нельзя
__________________
Axapta v.3.0 sp5 kr2 |
|
20.04.2015, 14:24 | #16 |
Участник
|
Коннекшен для TempDB неважен
Недавно приводили пример, как может заполняться таблица на самом SQL-сервере в хранимой процедуре Для доступа к этой таблице достаточно передать ее имя (уникальное для сессии)
__________________
Axapta v.3.0 sp5 kr2 |
|
20.04.2015, 14:43 | #17 |
Участник
|
Это как? Другой пользователь/сеанс может увидеть "мои" временные данные?
Цитата:
На практике, гарантировать "не переключение" соединения на уровне Axapta можно только путем прямого контроля за объектом Connection. Все остальное - это "как повезет". Может получиться, а может и нет... Тот факт, что, как правило, Axapta "держит" текущее соединение до окончания обработки, как раз и относится к таким "везениям". Некое действие по умолчанию, которое программист контролировать не может. Поэтому строить на этом какие-то далеко идущие выводы - не стоит.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
20.04.2015, 14:52 | #18 |
Участник
|
Цитата:
Одно условие - он должен знать имя таблицы (не аксаптовское, а физическое, что-нибудь типа такого [tempdb].[dbo].[t100005_E51B88936E814961BE9EFF89CE81E8D4]). Насчет сессии, повторюсь, совершенно неважно Я в Менеджмент студии руками заполнял значения таблицы, которая отображалась в интерфейсе аксапты Насчет "удержания соединения" - это уже задача программиста, что бы оно удерживалось на время работы стороннего средства)
__________________
Axapta v.3.0 sp5 kr2 |
|
20.04.2015, 17:08 | #19 |
Участник
|
Цитата:
Сообщение от AndyD
Не смешивайте, пожалуйста)
Для InMemory и в 2012 нельзя Цитата:
X++: TmpTable tmpTable; //fill tmpTable thread = new Thread(); thread.setInputParm([tmpTable.getPhysicalTableName()]); thread.removeOnComplete(true); thread.run(classnum(MyClass), staticmethodstr(MyClass, runThread)); thread.waitUntilSignaled(); // tmpTable после работы Thread
__________________
AxAssist 2012 - Productivity Tool for Dynamics AX 2012/2009/4.0/3.0 |
|
20.04.2015, 20:24 | #20 |
Участник
|
Цитата:
Тот факт, что у имени таблицы отсутствует ведущий символ "#", идентифицирующий именно временную таблицу в терминах MS SQL - это особенности "перевода" (пример) или действительно таблица создается в узле Table, а не в узле "Temporary Tables" базы данных tempdb? В смысле, если смотреть через MS SQL Server Management Studio. Т.е. с точки зрения MS SQL - это именно временная таблица, живущая только в текущем соединении, или постоянная таблица просто созданная в базе tempdb?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
Теги |
ax2009, thread, временная таблица |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|