Вместо @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
Использование:
@TransactionAttribute(javax.ejb.TransactionAttributeType.NOT_SUPPORTED)
Это позволяет компоненту без состояния избегать присоединения к текущей выполняющейся транзакции; и запустить, как будто нет транзакции вообще ...
Почему присутствует транзакция?
blockquote>Я действительно не знаю ... Вы вызывали какой-либо другой компонент J2EE (например, компонент CDI с аннотацией
@Transactional
или другой EJB) перед вызовом вашего компонента без гражданства?
У меня была та же проблема, и я узнал, что не должен создавать скрытое окно только для получения сообщений. Потоки уже имеют систему обмена сообщениями.
Я думаю, что Вы создаете свой дескриптор окон и храните его в fHandle, но GetMessage проверяет цикл сообщения Вашего потока. Поэтому сообщение PostMessage (fHandle, WM_QUIT, 0, 0); никогда не получается getmesssage.
Можно добавить сообщения к использованию потока PostThreadMessage, и в потоке Вы используете GetMessage (CurrentMessage, 0, 0, 0). Единственное важное различие - то, что необходимо запустить цикл сообщения с потока путем вызова
PeekMessage(CurrentMessage, 0, WM_USER, WM_USER, PM_NOREMOVE);
Необходимо запустить с этого, чем делают установку и, чем запускают цикл.
Причина, почему необходимо запустить с сообщения быстрого взгляда, состоит в том, чтобы удостовериться сообщения, которые отправляются во время инициализации threadprocedure, не потеряны.
Странная вещь, в данный момент я не могу найти ссылку, где я изучил это, но мое предположение является сообществом группы новостей.
Если я могу указать на немного проблем в Вашем коде...
1) Вы не проверяете вывод AllocateHwnd. Да, по всей вероятности это никогда не перестанет работать, но все еще...
2) AllocateHwnd belogs Из попытки.. наконец! Если это перестало работать, DeallocateHwnd нельзя назвать.
3) AllocateHwnd не ориентирован на многопотоковое исполнение. При вызове его от нескольких потоков одновременно можно столкнуться с poblems.Читать дальше.
Как Davy сказал, используйте MsgWaitForMultipleObjects вместо того, чтобы создать скрытое окно сообщения. Затем используйте PostThreadMessage для отправки сообщений для поточной обработки.
Если я могу поместить разъем для полностью бесплатного продукта здесь - используют мой OmniThreadLibrary вместо этого. Намного более простой, чем питание непосредственно с обменом сообщениями Windows.
1) Вам не нужно в AllocateHwnd в Вашем потоке. Сначала звоните в GetMessage, создаст отдельную очередь сообщений для этого потока. Но для отправки сообщения в поток, необходимо использовать функцию PostThreadMessage.
Знайте, что во время вызова PostThreadMessage очередь все еще не могла быть создана. Я обычно использую конструкцию:
while not PostThreadMessage(ThreadID, idStartMessage, 0, 0) do
Sleep(1);
гарантировать ту созданную очередь сообщений.
2) Для завершения цикла потока я определяю свое собственное сообщение:
idExitMessage = WM_USER + 777; // you are free to use your own constant here
3) Нет никакой потребности в отдельном событии, потому что можно передать дескриптор потока функции WaitForSingleObject. Так, Ваш код мог быть похожим:
PostThreadMessage(ThreadID, idExitMessage, 0, 0);
WaitForSingleObject(ThreadHandle, INFINITE);
Учтите, что ThreadID и ThreadHandle являются различными значениями.
4) Так, Ваш ThreadProc будет похож:
procedure ThreadProcFQM; stdcall;
var
Msg: TMsg;
begin
while GetMessage(Msg, 0, 0, 0)
and (Msg.Message <> idExitMessage) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;