Как это работает? Безопасность в одном потоке...

Тема в разделе "WASM.WIN32", создана пользователем demidov, 22 фев 2007.

  1. demidov

    demidov New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    2
    Привет! Прога на C, но вопрос общий. Происходит наслоение сообщений таймера. Вот грубый пример.

    //окна выскакивают без остановки
    void OnTimer()
    {
    MessageBox(hMainWnd, "Таймер. ", szCaption, MB_ICONERROR|MB_OK);
    ...

    //окна тоже выскакивают без остановки. почему это не работает?
    CRITICAL_SECTION ScanCS;
    InitializeCriticalSection(&ScanCS);

    void OnTimer()
    {
    EnterCriticalSection(&ScanCS);
    MessageBox(hMainWnd, "Таймер. ", szCaption, MB_ICONERROR|MB_OK);
    LeaveCriticalSection(&ScanCS);
    ...

    //а это работает
    bool Timer = false;
    void OnTimer()
    {
    if (Timer)
    return;
    Timer = true;

    MessageBox(hMainWnd, "Таймер. ", szCaption, MB_ICONERROR|MB_OK);
    Timer = false;
    ...

    Как решать эту проблему грамотно? Кто-нибудь, обьясните как работает система в этом
    случае. Она что, не ждет обработки сообщения в OnTimer()? Если не ждет, почему Sleep() вместо MessageBox() тормозит, но лишних вызовов OnTimer() вроде нет.
     
  2. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    потому что поток может занимать критическую секцию сколько угодно раз. пользуйся вторым способом
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Таймер отключать надо на время обработки его события.
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    demidov
    Похоже что MessageBox не тормозит обработку сообщений главного окна, то есть где-то в недрах MessageBox-a есть метод который передаёт управление главному окну, и это правильно. Можешь тормознуть таймер при входе в процедуру, и перед выходом снова запустить, или делай как делал ты в последнем примере.
     
  5. demidov

    demidov New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    2
    Спасибо. Остается непонятно почему при Sleep() наслоения, вроде, не происходит.
    if (Timer)
    {
    dbg(" return");
    return;
    }
    ничего не дает.
    Видимо, с MessageBox-ом неудачный пример. У меня просто долгая обработка данных в OnTimer(). Может ли "забиться" очередь сообщений?
    ...
    Вот еще нашел в MSDN: "The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions post this message only when no other higher-priority messages are in the thread's message queue." Похоже, с WM_TIMER проблем быть не должно...
     
  6. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    MessageBox создает внутри цикл обработки сообщений, поэтому функция вызывается повторно
    а насчет очереди - хз
    попробуй, проверь
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Cообщения WM_TIMER спариваются, то есть по идее они накапливаться не должы, а всегда только те время которых ещё не пришло.
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494