Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.136.97.64] |
|
Сообщ.
#1
,
|
|
|
Вот такое событие есть в имеющемся у меня компоненте:
void __fastcall TForm1::CommPortReceiveData(TObject *Sender, Pointer DataPtr, DWORD DataSize) Как его присоединить к потоку: void __fastcall ReceiveData::Execute() { } Понятно что нужно создать экземпляр класса, а дальше как? |
Сообщ.
#2
,
|
|
|
Цитата misyachniy @ Вот такое событие есть в имеющемся у меня компоненте: void __fastcall TForm1::CommPortReceiveData(TObject *Sender, Pointer DataPtr, DWORD DataSize) Как его присоединить к потоку. Попробуй посредством события void __fastcall TForm1::CommPortReceiveData(TObject *Sender, Pointer DataPtr, DWORD DataSize); //... //... взвести Эвент. А в потоковой процедуре void __fastcall ReceiveData::Execute() { //... //... } используй ожидание эвента: WaitResult = ::WaitForMultipleObjects (...); switch (WaitResult) { case WAIT_OBJECT_0: //.. break; case WAIT_OBJECT_0+1: //.. break; case WAIT_OBJECT_0+2: //.. break; //.. //.. Возможно, других нужных эвентов тоже. И, конечно, все это удобнее делать в одном классе - "CommPortAsync" - "КоммПортАсинхронный". Это потому удобно, что ::WaitForMultipleObjects может сама ожидать события приема байт. Смастерим "ребенка" от TThread и легко решим проблему. |
Сообщ.
#3
,
|
|
|
А что за компонента? Если не твоя, то большинство из тех, что я знаю, уже имеют встроенные потоки.
|
Сообщ.
#4
,
|
|
|
А почему не использовать WaitForSingleObject вместо WaitForMultipleObjects?
|
Сообщ.
#5
,
|
|
|
Цитата misyachniy @ А почему не использовать WaitForSingleObject вместо WaitForMultipleObjects? Использовать безусловно можно. Но я привел вариант более общего случая. Когда я писал класс-CommPort мне понадобился именно WaitForMultipleObjects. Имеется и другое соображение: минимум - это 2 события. Одно событие - для приема байт. 2-е событие - для нормального завершения потока. Так что Multiple на мой взгляд лучше подходит. |
Сообщ.
#6
,
|
|
|
Понятно. Я нашел такой пример c while (bSomeCondition)
unsigned __stdcall CaptureThreadFunc( void * arg) // Поток, готовящий данные { while (bSomeCondition) { WaitForSingleObject(m_hEventForCaptureTh,INFINITE); // Ждем своего события ... // Готовим данные SetEvent(hEventForTransmitTh); // Разрешаем работать второму потоку } _endthreadex( 0 ); return 0; }; Если даже поменять условие bSomeCondition поток не будет завершен, юудет ждать WaitForSingleObject. Тему можно закрыть. |
Сообщ.
#7
,
|
|
|
Что-то я поспешил с закрытием темы.
Объявил два события для удобства сделал дефайны. HANDLE hParcerThreads[2]; #define eStopParcer hParcerThreads[0] #define eResumeParcer hParcerThreads[1] //при создании формы // Создаем два события с автосбросом, со сброшенным начальным состоянием eStopParcer=CreateEvent(NULL,FALSE,FALSE,NULL); eResumeParcer=CreateEvent(NULL,FALSE,FALSE,NULL); // создаем поток разборщика пакетов tParcer= new TParcerData(true); // tParcer->Priority = tpLower; // set the priority lower than normal tParcer->Resume(); // now start the thread running //по приему пакета взвожу событие SetEvent(eResumeParcer); //Взводиться только один раз(доходит оператора switch) WaitResult= ::WaitForMultipleObjects(2, hParcerThreads, FALSE, INFINITE ); switch (WaitResult) Где нужно править? ! ------------------------------------------- Используйте теги [СODE][/CODE] для оформления кода |
Сообщ.
#8
,
|
|
|
Цитата misyachniy @ Где нужно править? Не понял - в чем именно проблема ? Допустим, работает протоковая процедура: //--------------------------------------------------------------------------- int WINAPI TThreadChild::Execute () { for (;;) { if ( GetTerminate () ) break; WaitResult = ::WaitForMultipleObjects ( 2, // number of handles in the object handle array hParcerThreads, // pointer to the object-handle array false, // wait flag 5000 // time-out interval in milliseconds ); switch (WaitResult) { case WAIT_OBJECT_0: // тут принимаем байты - рабочее сосояние break; case WAIT_OBJECT_0+1: // состояние выхода SetTerminate(); break; case WAIT_TIMEOUT: break; } } return 0; } Когда взводится "рабочий" эвент, начинается некая полезная работа. Когда обработка заканчивается, потоковая процедура снова "WAIT". Если надо ликвидировать поток, выставляется второй эвент. Вот собственно и вся структура. (Билдером я это сейчас не компилировал, возможны мелкие огрехи) |
Сообщ.
#9
,
|
|
|
Вопрос в том что я взвожу событые каждый раз по приему пакета.
SetEvent(eResumeParcer); А присвоение WaitResult происходит только один раз WaitResult= ::WaitForMultipleObjects(2, hParcerThreads, FALSE, INFINITE ); Может происходит накладка и взводиться событие которое уже во взведенном состоянии? |
Сообщ.
#10
,
|
|
|
Цитата misyachniy @ Может происходит накладка и взводиться событие которое уже во взведенном состоянии? Если что то "не так", то проблема конечно есть. Но если событие не сбрасывается, то Wait не будет больше ждать никогда. Но если Wait запустился хоть один раз, значит событие будет сброшено. (Если эвент спрограммирован на автоматический сброс) Теоретически можно предполагать, что взвод 2-й раз происходит до начала выхода Wait из спячки. Тогда возможно пакеты будут теряться. У меня такого не было. Но тут надо расчитывать возможности твоей программы. Попробуй для эксперимента снизить частоту взвода событий. Что будет ? |
Сообщ.
#11
,
|
|
|
Через WaitForSingleObject. у меня работала программа.
Но чтобы избежать ситуации как в посте №6 переписал под WaitForMultipleObjects Прийдется наверное вернуть все обратно. |