问题:由于m_TimerTest.Test的调用,出现线程阻塞,要求不采用多线程,能否解决?如何解决?调用:
VOID CMainFrm::OnCreate(HWND hWnd)
{
    m_TimerTest.Test((WNDPROC)Test);
    // ★ 由于m_TimerTest.Test的调用,◇这◇里◇出现线程阻塞,如何解决?
}函数:
VOID CTimer::Test(WNDPROC pfnTest)
{
    m_hTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
    // 创建
    SYSTEMTIME st;
    FILETIME ftLocal, ftUTC;
    LARGE_INTEGER liUTC;
    st.wYear = 2007;
    st.wMonth = 5;
    st.wDay = 2;
    st.wHour = 8;
    st.wMinute = 14;
    st.wSecond = 0;
    st.wMilliseconds = 0;
    ::SystemTimeToFileTime(&st, &ftLocal);
    //convert local time to UTC time
    ::LocalFileTimeToFileTime(&ftLocal, &ftUTC);
    //convert FILETIME to LARGE_INTEGER because of different alignment
    liUTC.LowPart = ftUTC.dwLowDateTime;
    liUTC.HighPart = ftUTC.dwHighDateTime;
    BOOL bSuccess = ::SetWaitableTimer(m_hTimer, &liUTC, 3000, (PTIMERAPCROUTINE)pfnTest, NULL, FALSE);
    if ( bSuccess ) 
    {
        for (int i = 0; i < 5; i++) 
        {
            SleepEx(
                INFINITE,     // Wait forever
                FALSE);       // Put thread in an alertable state
        }
    }
}

解决方案 »

  1.   

    你最后加这个想做什么???
    if ( bSuccess )
    {
    for (int i = 0; i < 5; i++)
    {
    SleepEx(
    INFINITE, // Wait forever
    FALSE); // Put thread in an alertable state
    }
    }
      

  2.   

    VOID CTimer::Test(WNDPROC pfnTest):这里传入一个函数地址,将通过:
    BOOL bSuccess = ::SetWaitableTimer(m_hTimer, &liUTC, 3000, (PTIMERAPCROUTINE)pfnTest, NULL, FALSE);
    将传入的函数当作回调函数。作用:指定时间之后每三秒调用一次传入的函数。
      

  3.   

    抱歉,最后一个参数写错了:
    for (int i = 0; i < 5; i++) 
            {
                SleepEx(
                    INFINITE,     // Wait forever
                    TRUE);       // 这个参数应该是 TRUE
            }
    如果不加这个循环,则无法实现每3秒提醒一次。
      

  4.   

    可能我没仔细看,搞混了CreateTimerQueueTimer与CreateWaitableTimer的区别用线程池函数CreateTimerQueueTimermsdn上的例子:
    #include <windows.h>
    #include <stdio.h>HANDLE gDoneEvent;VOID CALLBACK TimerRoutine(PVOID lpParam, BOOL TimerOrWaitFired)
    {
        if (lpParam == NULL)
        {
            printf("TimerRoutine lpParam is NULL\n");
        }
        else
        {
            // lpParam points to the argument; in this case it is an int        printf("Timer routine called. Parameter is %d.\n", 
                    *(int*)lpParam);
        }    SetEvent(gDoneEvent);
    }int main()
    {
        HANDLE hTimer = NULL;
        HANDLE hTimerQueue = NULL;
        int arg = 123;    // Use an event object to track the TimerRoutine execution
        gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!gDoneEvent)
        {
            printf("CreateEvent failed (%d)\n", GetLastError());
            return 1;
        }    // Create the timer queue.
        hTimerQueue = CreateTimerQueue();
        if (!hTimerQueue)
        {
            printf("CreateTimerQueue failed (%d)\n", GetLastError());
            return 2;
        }    // Set a timer to call the timer routine in 10 seconds.
        if (!CreateTimerQueueTimer(
            &hTimer, hTimerQueue, TimerRoutine, &arg , 10000, 0, 0))
        {
            printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());
            return 3;
        }    // TODO: Do other useful work here     printf("Call timer routine in 10 seconds...\n");    // Wait for the timer-queue thread to complete using an event 
        // object. The thread will signal the event at that time.    if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)
            printf("WaitForSingleObject failed (%d)\n", GetLastError());    // Delete all timers in the timer queue.
        if (!DeleteTimerQueue(hTimerQueue))
            printf("DeleteTimerQueue failed (%d)\n", GetLastError());    return 0;
    }
      

  5.   

    顶上去。希望给个CreateWaitableTimer 的完整例子。
      

  6.   

    把SleepEx()换成MsgWaitForMultipleObjectsEx()即可
      

  7.   

    当然,有消息的时候要PeekMessage()/TranslateMessage()/DispatchMessage()
    如果不止等一次Timer的话,外面还需要加一个循环
      

  8.   

    if ( bSuccess ) 
        {
            for (int i = 0; i < 5; i++) 
            {
                SleepEx(
                    INFINITE,     // Wait forever
                    FALSE);       // Put thread in an alertable state
            }
        }
    换成:
    if ( bSuccess ) 
       SleepEx(
                    INFINITE,     // Wait forever
                    FALSE);       // Put thread in an alertable state
      

  9.   

    写错了:
    if ( bSuccess ) 
        {
            for (int i = 0; i < 5; i++) 
            {
                SleepEx(
                    INFINITE,     // Wait forever
                    FALSE);       // Put thread in an alertable state
            }
        }
    换成:
    if ( bSuccess ) 
       SleepEx(
                    INFINITE,     // Wait forever
                    TRUE);       // Put thread in an alertable state
      

  10.   

    CreateWaitableTimer实例#define _WIN32_WINNT 0x0400#include <windows.h>
    #include <process.h>
    #include <stdio.h>unsigned __stdcall TF(void* arg) {
      HANDLE timer=(HANDLE) arg;  while (1) {
        WaitForSingleObject(timer,INFINITE);
        printf(".");
      }}int main(int argc, char* argv[]) {  HANDLE timer = CreateWaitableTimer(
        0,
        false, // false=>will be automatically reset
        0);    // name  LARGE_INTEGER li;  const int unitsPerSecond=10*1000*1000; // 100 nano seconds  // Set the event the first time 2 seconds
      // after calling SetWaitableTimer  li.QuadPart=-(2*unitsPerSecond);
      SetWaitableTimer(
        timer,
        &li,
        750,   // Set the event every 750 milli Seconds
        0,
        0,
        false);  _beginthreadex(0,0,TF,(void*) timer,0,0);  // Wait forever, 
      while (1) ;  return 0;
    }原帖:http://www.adp-gmbh.ch/win/misc/timer.html