События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 25.07.02 05:29
Оценка:
Есть компонент (ATL), а в нем отдельный 'worker thread', который время от времени рождает события, об которых надо сообщать клиенту на VB. Для этого посылает WM_MY окну компонента, оно зажигает событие. Зажигать Еvent из 'worker thread' нельзя (он не должен тормозиться)
Проблема : Если во время обработки одного события в VB (висмт MsgBox) на компонент падает второе WM_MY, он зажигает событие, но это второе просто 'проглатывается' в VB
Вопрос : Есть какой-нибудь простой метод дождаться, пока первый Event отработает, и только потом бросать на клиента второй ? Или делать это надо как-то иначе ?
Re: События из worker thread
От: Максим Алексейкин Россия  
Дата: 25.07.02 11:36
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Есть компонент (ATL), а в нем отдельный 'worker thread', который время от времени рождает события, об которых надо сообщать клиенту на VB. Для этого посылает WM_MY окну компонента, оно зажигает событие. Зажигать Еvent из 'worker thread' нельзя (он не должен тормозиться)

bnk>Проблема : Если во время обработки одного события в VB (висмт MsgBox) на компонент падает второе WM_MY, он зажигает событие, но это второе просто 'проглатывается' в VB
bnk>Вопрос : Есть какой-нибудь простой метод дождаться, пока первый Event отработает, и только потом бросать на клиента второй ? Или делать это надо как-то иначе ?

Event обрабатывается синхронно. Т.е. пока твой конрол и VB не обработали первый, второй евент не возникнет. Может как второй WM_MY не доходит до окна контрола?
ICQ #311116826
Re[2]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 25.07.02 12:02
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Event обрабатывается синхронно. Т.е. пока твой конрол и VB не обработали первый, второй евент не возникнет. Может как второй WM_MY не доходит до окна контрола?


Максим, проблема в том что второй евент возникает. Я проверял в дебаггере, ситуация следующая: Входит в обработчик WM_MY, запускается Fire_MY(..), после чего, не выходя из этого обработчика , входит в него повторно ха-ха и снова делает Fire_MY()
Происходит енто, я думаю, потому, что WM_MY's посылаются компоненту той самой 'worker thread' (асинхронно), а когда компонент ожидает 'окончания евета' в Fire_MY(), он радостно диспатчит все WM_xx, и входит в обработчик повторно.
В чем и вопрос, с какой стороны это безобразие можно объехать
Re[3]: События из worker thread
От: Максим Алексейкин Россия  
Дата: 25.07.02 14:30
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Здравствуйте Максим Алексейкин, Вы писали:


МА>>Event обрабатывается синхронно. Т.е. пока твой конрол и VB не обработали первый, второй евент не возникнет. Может как второй WM_MY не доходит до окна контрола?


bnk>Максим, проблема в том что второй евент возникает. Я проверял в дебаггере, ситуация следующая: Входит в обработчик WM_MY, запускается Fire_MY(..), после чего, не выходя из этого обработчика , входит в него повторно ха-ха и снова делает Fire_MY()

bnk>Происходит енто, я думаю, потому, что WM_MY's посылаются компоненту той самой 'worker thread' (асинхронно), а когда компонент ожидает 'окончания евета' в Fire_MY(), он радостно диспатчит все WM_xx, и входит в обработчик повторно.
bnk>В чем и вопрос, с какой стороны это безобразие можно объехать

Попробуй ограничить доступ к Fire_MY() при помощи критической секции. Т.е. пока не вернулся из первого евента не делать следующие.
Удачи.
ICQ #311116826
Re[3]: События из worker thread
От: George_Seryakov Россия  
Дата: 25.07.02 14:30
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Максим, проблема в том что второй евент возникает. Я проверял в дебаггере, ситуация следующая: Входит в обработчик WM_MY, запускается Fire_MY(..), после чего, не выходя из этого обработчика , входит в него повторно ха-ха и снова делает Fire_MY()


bnk>В чем и вопрос, с какой стороны это безобразие можно объехать


Поставь критсекцию на вызов Fire_MY():

CComAutoCriticalSection cs; // global 
...

cs.Lock();
Fire_MY();
cs.Unlock();


Либо то же самое через объект, лочащий при создании и т.п.
GS
Re[4]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 06:00
Оценка:
Здравствуйте George_Seryakov, Вы писали:

GS>Здравствуйте bnk, Вы писали:


GS>Поставь критсекцию на вызов Fire_MY():

Спасибо за совет, но это не проходит, т.к. ниточка, входящая в обработчик WM_MY, одна и та же при первом и при втором вхождении :). Так что при попытке войти в CS во второй раз все просто повисает.

Насчет
GS> CComAutoCriticalSection cs; // global


Мне думается, что CComAutoCriticalSection + Single-thread-appartament = Nothing

Мне пока удалось изобрести вот какой объезд на эту проблему :-
list<pair<WPARAM, LPARAM> > m_queue;

LRESULT CCmdShell::OnMY(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  m_queue.push_back(make_pair(wParam,lParam));

  if (m_messages.size() == 1)  // inside only at 'first' entry
  {
     while (m_queue.size() > 0) // size may be added with 'recursive' calls
     {
         pair<WPARAM,LPARAM> p = m_queue.front();
         Fire_MY(...);  // <-- 'recursive' call from here
         m_queue.pop_front();
     }
  }
}
Re: События из worker thread
От: Tom Россия http://www.RSDN.ru
Дата: 26.07.02 06:22
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Есть компонент (ATL), а в нем отдельный 'worker thread', который время от времени рождает события, об которых надо сообщать клиенту на VB. Для этого посылает WM_MY окну компонента, оно зажигает событие. Зажигать Еvent из 'worker thread' нельзя (он не должен тормозиться)

bnk>Проблема : Если во время обработки одного события в VB (висмт MsgBox) на компонент падает второе WM_MY, он зажигает событие, но это второе просто 'проглатывается' в VB
bnk>Вопрос : Есть какой-нибудь простой метод дождаться, пока первый Event отработает, и только потом бросать на клиента второй ? Или делать это надо как-то иначе ?

Проблемма состоит в том, что вы АБСОЛЮТНО ИЗВРАЩЁННО реализуете механизм событий. Для таких вещей есть ConnectionPoint..., причём я решал задачу полностью похожую на вашу при помощи ConnectionPoint. (особых проблемм там быть не должно) Если решитесь переделать, то могу помочь кодом (стандартная реализация механизма точек стыковки из ATL вам не подойдёт, так как вы будете вызывать события не из того потока, в котором VB будет "садится" на события и придётся воспользоваться маршалингом, но это довольно просто)
Народная мудрось
всем все никому ничего(с).
Re[2]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 06:50
Оценка:
Здравствуйте Tom, Вы писали:

Tom>Проблемма состоит в том, что вы АБСОЛЮТНО ИЗВРАЩЁННО реализуете механизм событий. Для таких вещей есть ConnectionPoint...,



Многоуважаемый Tom, я думаю, что знаю, что такое ConnectionPoint, и с чем ее едят. В письме я подразумевал под 'зажечь event' именно вызов через ConnectionPoint. Я понимаю, что можно зажечь event из второй thread, и знаю, как отмаршалить InterfacePointer для этого. Проблема в том, что Зажигать Event из этой thread нельзя, т.к., повторяю, этот thread Не должен тормозиться, а именно это и произойдет, если сделать вызов на ConnectionPoint оттуда.
Re: События из worker thread
От: Ivan Россия www.rsdn.ru
Дата: 26.07.02 07:02
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Есть компонент (ATL), а в нем отдельный 'worker thread', который время от времени рождает события, об которых надо сообщать клиенту на VB. Для этого посылает WM_MY окну компонента, оно зажигает событие. Зажигать Еvent из 'worker thread' нельзя (он не должен тормозиться)

bnk>Проблема : Если во время обработки одного события в VB (висмт MsgBox) на компонент падает второе WM_MY, он зажигает событие, но это второе просто 'проглатывается' в VB
bnk>Вопрос : Есть какой-нибудь простой метод дождаться, пока первый Event отработает, и только потом бросать на клиента второй ? Или делать это надо как-то иначе ?

ЭТО Q178078 случайно не про твою ситуацию ?
Re[2]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 07:14
Оценка:
Здравствуйте Ivan, Вы писали:

I>ЭТО Q178078 случайно не про твою ситуацию ?


Нет, к сожалению Здесь компонент создается из MSAccessa. Но события действительно _НЕ_ случаются, как и должно быть, согласно Q178078. Да я и не хочу, чтобы они случались, пока висит этот чертов MsgBox, но я хочу, чтобы они случились после того, как он ичезнет, черт побери, а не пропали неизвесто где.
Re[3]: События из worker thread
От: Ivan Россия www.rsdn.ru
Дата: 26.07.02 07:22
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Здравствуйте Ivan, Вы писали:


I>>ЭТО Q178078 случайно не про твою ситуацию ?


bnk>Нет, к сожалению Здесь компонент создается из MSAccessa. Но события действительно _НЕ_ случаются, как и должно быть, согласно Q178078. Да я и не хочу, чтобы они случались, пока висит этот чертов MsgBox, но я хочу, чтобы они случились после того, как он ичезнет, черт побери, а не пропали неизвесто где.


А при выполенении VB кода как exe-шника (не из IDE) они тоже пропадают ?
Re[4]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 07:54
Оценка:
Здравствуйте Ivan, Вы писали:

I>А при выполенении VB кода как exe-шника (не из IDE) они тоже пропадают ?


Нет, в этом случае они НЕ пропадают , но, согласно тому же Q178078, это не есть хорошо, это есть БАГ у VB, ха-ха.
У меня ситуация близка скорее к описанной в Q196026, но только там не написано, что будет, если worker thread вздумает послать не одно, а несколько сообщений. А будет, похоже, то самое, что они исчезнут, яко тени в полдень, если об этом специально не позаботиться. Я что-то изобрел по этому поводу (см. Re[4] на George_Seryakov), это в общем-то работает, но я не уверен, наколько это есть хорошо...
Re[5]: События из worker thread
От: Ivan Россия www.rsdn.ru
Дата: 26.07.02 08:05
Оценка:
Здравствуйте bnk, Вы писали:

bnk>Здравствуйте Ivan, Вы писали:



bnk>Нет, в этом случае они НЕ пропадают , но, согласно тому же Q178078, это не есть хорошо, это есть БАГ у VB, ха-ха.


Позволю себе не согласиться. В статье написано , что это поведение by design. Так себя ведет VB IDE.
Ничего страшного в этом нет, главное, что готовое приложение будет работать нормально, а на IDE можно не обращать внимание ( или убрать messagebox из обработчика события)


bnk>У меня ситуация близка скорее к описанной в Q196026, но только там не написано, что будет, если worker thread вздумает послать не одно, а несколько сообщений.


А эта статья ИМХО совсем о другом — когда ты файришь события из другого потока, не замаршалив указатель на синк.К твоей ситуации это неприменимо, так как ты, я так понимаю, файришь события из основного потока.
Re[6]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 08:22
Оценка:
Здравствуйте Ivan, Вы писали:

I>Позволю себе не согласиться. В статье написано , что это поведение by design. Так себя ведет VB IDE.


К сожалению в статье Q178078 ('98) написано, что это EXE файл ведет себя неправильно(!): 'The behavior in the EXE is incorrect; events should not occur while a Message box is displayed', а в IDE все "хорошо".

А к статье Q196026 это имеет отношение в части того, как предлагается решать проблему маршалинга — сделать окно и послать на него сообщение. Так вот, моя проблема будет, если послать не одно, а несколько сообщений. Во время того, как в VB отрабатывается первый ConnectinoPoint, почему-то диспатчатся остальные посланные сообщения, и начинает отрабатывать второй, который и игнорируется в VB.
Re[7]: События из worker thread
От: Ivan Россия www.rsdn.ru
Дата: 26.07.02 08:34
Оценка:
Здравствуйте bnk, Вы писали:

Странно, в моей статье (которая на сайте www.microsoft.com) написано вот что
Symptoms
Running a project in the IDE that displays a message box prevents events from occurring. However, when you compile and run the same project as an executable file (EXE), the events occur while the message box is displayed.
Cause
The behavior in the EXE has changed with Microsoft Visual Basic 5.0 and 6.0 so that it is different from earlier versions of Microsoft Visual Basic.


Про "incorrect" там ничего нет
Re[7]: А модель какая?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 26.07.02 08:47
Оценка:
Здравствуйте bnk, Вы писали:

bnk>А к статье Q196026 это имеет отношение в части того, как предлагается решать проблему маршалинга — сделать окно и послать на него сообщение. Так вот, моя проблема будет, если послать не одно, а несколько сообщений. Во время того, как в VB отрабатывается первый ConnectinoPoint, почему-то диспатчатся остальные посланные сообщения, и начинает отрабатывать второй, который и игнорируется в VB.


А модель какая? По-видимому FreeThreaded.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: События из worker thread
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 08:59
Оценка:
Здравствуйте Ivan, Вы писали:

I>Про "incorrect" там ничего нет


Странно, но факт. В моем MSDN написано вот что:
Last reviewed: November 20, 1998
SYMPTOMS
Running a project in the IDE that displays a message box prevents events from occurring. However, when you compile and run the same project as an executable file (EXE), the events occur while the message box is displayed.
CAUSE
The behavior in the EXE is incorrect; events should not occur while a Message box is displayed (as with earlier versions of Microsoft Visual Basic).

На www.microsoft.com стоит дата публикации 'First Published: Dec 15 1997'
Может быть, они там редко обновляют статьи ?
Re[8]: А модель какая?
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.07.02 09:04
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>А модель какая? По-видимому FreeThreaded.


Нет. CComSingleThreadModel.
Re[9]: А модель какая?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 26.07.02 09:09
Оценка:
Здравствуйте bnk, Вы писали:

Vi2>>А модель какая? По-видимому FreeThreaded.

bnk>Нет. CComSingleThreadModel.

Тогда может посмотришь статью Понимание подразделений COM
Автор(ы): Jeff Prosise
Дата: 22.02.2001

В этой статье подробно рассматриваются подразделения (apartments) в модели
COM. Автор описывает различные виды подразделений, показывает, каким образом
подразделения назначаются потокам и объектам, а также даёт ряд полезных
советов, которые позволят вам избежать ошибок при работе с подразделениями.
?
Может там есть решение для тебя.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[9]: События из worker thread
От: Ivan Россия www.rsdn.ru
Дата: 26.07.02 09:12
Оценка:
Здравствуйте bnk, Вы писали:

bnk>На www.microsoft.com стоит дата публикации 'First Published: Dec 15 1997'

bnk>Может быть, они там редко обновляют статьи ? :-
У меня MSDN — April 2002 и там то же самое, что и на www.microsoft.com
Я сталкивался с такой проблемой — VB "глотает" события, когда в обработчике вызывается MessageBox и, действительно, это происходит только в IDE, а при запуске как exe — не "глотает". Ну а "by design", так "by design". Советую не обращать внимания на эту странность IDE
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.