vc++ 多方案实现定时执行任务

1、常用的方法是SetTimer,但WM_TIMER消息的优先级是低级别的。

      这种消息只会在线程的消息队列中没有更高级的消息,才会被处理。


2、使用waitable timer oject

     2.1 创建一个 waitable timer

       HANDLE CreateWaitableTimer( PSECURITY_ATTRIBUTES psa, BOOL bManualReset, PCTSTR pszName);

       bManualReset:用于标识此timer是人工重置的还是自动重置的。

       如果是人工重置的Timer,当此timer处于触发状态(signaled)时,所有等待此timer的线程都会变成可调度状态;

       如果是自动重置的Timer,当此timer处于触发状态(signaled)时,所有等待此timer的线程中只要一个线程变成可调度状态。


    2.2 打开一个已存在的waitable timer

       HANDLE OpenWaitableTimer( PSECURITY_ATTRIBUTES psa, BOOL bInheritHandle, PCTSTR pszName);


    2.3 设置waitable timer,waitable timer在创建后是处于非触发状态的(nonsignaled)。

          BOOL SetWaitableTimer( HANDLE hTimer,
                                                   const LARGE_INTEGER *pDueTime,
                                                   LONG lPeriod,
                                                  PTIMERAPCROUTINE pfnCompletionRoutine,
                                                  PVOID pvArgToCompletionRoutine,
                                                  BOOL bResume);

          pDueTime: 用于指定第一次触发Timer的时间。

          lPeriod:用于指定第一次触发之后,再次被触发的时间间隔。          

          pfnCompletionRoutine:timer被触发后的回调函数(可选的)。

                  执行回调函数的线程和执行SetWaitableTimer函数的线程是同一个。

                  回调函数的原型为:

                 VOID APIENTRY TimerAPCRoutine(PVOID pvArgToCompletionRoutine,

                                                                                DWORD dwTimerLowValue,

                                                                                DWORD  dwTimerHighValue);

 

         注:执行SetWaitableTimer函数的线程必须是处于可alertable状态,否则回调函数不会被执行。

                 执行下面的函数函数可使处于可alertable状态

                 SleepEx,WitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx, SignalObjectAndWait

        

    2.4  注销waitable timer

            BOOL CancelWaitableTimer( HANDLE hTimer );

 

    2.5 注意          

          不要在同一个线程中即等待timer的句柄,又等待timer所在的线程处于可alertable状态。例如:

          HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
          SetWaitableTimer(hTimer, ..., TimerAPCRoutine,...);
          WaitForSingleObjectEx(hTimer, INFINITE, TRUE);

         当timer变成触发状态时,WaitForSingleObjectEx函数返回,并且线程从可alertable状态变成苏醒状态。

          因此造成TimerAPCRoutine不会被执行。

 

3、使用Thread pool Timer

     3.1 创建Thread pool Timer

          PTP_TIMER CreateThreadpoolTimer( PTP_TIMER_CALLBACK pfnTimerCallback,
                                                                             PVOID pvContext,
                                                                             PTP_CALLBACK_ENVIRON pcbe);

         pfnTimerCallback:回调函数。函数原型为:

             VOID CALLBACK TimeoutCallback(PTP_CALLBACK_INSTANCE pInstance,
                                                                            PVOID pvContext,
                                                                            P_TIMER pTimer);

 

     3.2 设置Thread pool Timer

            VOID SetThreadpoolTimer(PTP_TIMER pTimer,
                                                           PFILETIME pftDueTime,
                                                           DWORD msPeriod,
                                                           DWORD msWindowLength);

 

     3.3 注销Thread pool Timer

          VOID CloseThreadpoolTimer(PTP_TIMER pTimer);

 

 




    



VC 6.0 定时执行任务编写实例,程序运行时显示托盘图标和右键菜单,请设置好时间和需要执行的外部文件路径及文件名,默认情况下是执行外部任务,可选择执行关机、重启、注销等任务,然后启动定时程序,在仅剩1分钟时,程序会显示自动重启警告:计算机将于1分钟内重启,是否取消重启?按"是"则取消自动重启.若允许自动关闭,请保存尚未关闭的程序!"。   本定时程序时间的设置可精确到日期、时间、秒,编写步骤:   ①设置任务执行的日期时间.   ②选择关机,注销,重启,任务模式.   ③选择了任务模式,需要设置任务路径.   ④按下"启动定时"按钮.   ⑤关机前1分钟不段提示是否关机或重启,如果用户一直未取消,电脑将于1分钟内关机或重启.有如下代码可参考:   if(shutTime < CTime::GetCurrentTime())   {    MessageBox("设置的时间不能早于当前系统时间!");   }   else   {    CString bb;    cButton->GetWindowText(bb);    if(bb == "启动定时")    {    if(radio == 1)    {    MessageBox("定时关机已启动!","定时关机已启动");    }    else if(radio == 2)    {    MessageBox("定时注销已启动!","定时注销已启动");    }    else if(radio == 3)    {    MessageBox("定时重启已启动!","定时重启已启动");    }else if(radio == 4)    {    CString command = "";    GetDlgItemText(IDC_EDIT2,command);    if(command == "")    {    MessageBox("请选择要执行的文件!");    return ;    }else    {    MessageBox("定时任务已启动!","定时任务已启动");    }    }    SetTimer(1,1000,0);    AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE);       //cButton->SetButtonStyle(WS_DISABLED);    cButton->SetWindowText("停止定时");    }else    {    KillTimer(1);    cButton->SetWindowText("启动定时");    }   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值