Re[4]: Двойное срабатывание WaitCommEvent
От: _alecs Россия  
Дата: 20.02.08 15:05
Оценка:
Здравствуйте, CreatorCray, Вы писали:

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


CC>у тебя manual reset event — их же надо ручками сбрасывать иначе они все время будут в signaled state

CC>вероятно поэтому у тебя второй раз wait срабатывает сразу. Соответственно и данных нет, потому как они не поступили еще

Конечно ты прав, просто покоцылось кое-что когда выдёргивал часть кода... Конечно всё сбрасывается! Если бы не сбрасывалось срабатываний было бы гораздо больше!
А здесь чётко два. Такое впечатление, что когда WaitCommEvent присаживается на событие, то по приходу первого байта (события EV_RXCHAR) она вылетает и устанавливает oWait.hEvent. При этом флаг события EV_RXCHAR сбрасывается. По приходу остальных байт, из-за того что управление не дошло вновь до WaitCommEvent (переключение потоков и т.д.) устанавливается флаг события EV_RXCHAR. Потом когда управление вновь передаётся потоку и тот считывает все на этот момент поступившие данные флаг поступления события EV_RXCHAR остаётся в установленном состоянии. И когда функция WaitCommEvent опять лезет за событием, она сразу получает событие от предыдущих данных. Почти на 99% уверен что так и происходит, просто хотел узнать мнение остальных разработчиков. Сталкивались ли они с этим...? И как сбросить (элегантным способом!!) все события перед вызовом WaitCommEvent. И вообще, хочу услышать рассуждения других специалистов.

Вот уточнил:


SetCommMask( hCom, EV_RXCHAR );

while( ! Terminated )
{
    // Ожидаем событие от ком-порта.

    if ( ! WaitCommEvent( hCom, dwEvtMask, &oWait ) )
    {
        if ( GetLastError() != ERROR_IO_PENDING )
        {
            // Прекращаем выполнение программы.
            // ...
        }

        ResetEvent( oWait.hEvent );

        // Ожидаем окончания операции.
        HANDLE hEvents[] = { oWait.hEvent, hBreakEvent };

        DWORD dwWait = WaitForMultipleObjects(
            sizeof( hEvents ) / sizeof( HANDLE ),    // number of object handles
            hEvents,                // pointer to an array of object handles
            FALSE,                    // returns when the state of any one of the objects is set to signaled
            dwMilliseconds);            // waits indefinitely

        switch( dwWait )
        {
            case WAIT_OBJECT_0:
                
                // Считываем данные с ком-порта (считываются все переданные данные, потерянных нет).
                // ...
                break;

            case WAIT_OBJECT_0 + 1: continue;

            default:
                // Прекращаем выполнение программы.
                // CancelIo( hCom ); ...
        }
    }
    else
    {
        // Считываем данные с ком-порта (считываются все переданные данные, потерянных нет).
        // ...
    }
} // end-while
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.