zoukankan      html  css  js  c++  java
  • 定时器

    C#中实现定时的类很多。主要是三种:

    1.定义在System.Windows.Forms里   
    2.定义在System.Threading.Timer类里   
    3.定义在System.Timers.Timer类里  

    System.Windows.Form.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或者Delphi中的Timer控件,内部使用API SetTimer实现。它的主要缺点是计时不精确,而且必须有消息循环,Cosole Application(控制台应用程序)无法使用。

    System.Timers.Timer和System.Threading.Timer非常类似,他们是通过.Net Thread Pool实现的,轻量,计时精确,对应用程序、消息没有特别的要求。System.Timers.Timer还可以应用于WinForm,完全取代上面的Timer控件。它们的缺点是不支持直接的拖放,需要手工编码。

    这里我使用的是System.Timers.Timer类,所以这里只讲解下该类,其他的类后面用到再补上。

    System.Timers.Timer类

    实例化:

    System.Timers.Timer time = new System.Timers.Timer(1000);//这里是间隔1秒,因为单位是毫秒

    另外一种实例化方法:

    System.Timers.Timer time = new System.Timers.timer();

    time.Interval = 2000;//设置Interval参数也可以设置间隔时间

    到达后执行的函数:

    time.Elapsed += new Syatem.Timers.ElapsedEventHandler(theout);//到了1秒后执行函数theout

    设置相关参数:

    执行次数:time.AutoReset = true;//为True则是每过1秒执行一次,为False则是只执行一次

    是否执行函数:time.Enable = true;//为Ture则是执行函数theout,为False则是不执行函数theout

    下面是我自己写的一个功能,具体是:需要过2秒后执行函数CheckUpdatetimer_Elapsed,该代码实在C#的控件里面写的。

    函数CheckUpdatetimer_Elapsed为时间到后应该执行的函数。

            private void CheckUpdatetimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                lock(locko)
                {
                    if (m_PPTobjectGui.isPlaying())
                    {
                        m_PPTobjectGui.pause();
                    }
                    m_timer.Enabled = false;
                    m_timer.Close();
                }
            }
        //该函数是点击按钮后执行的函数
    private
    void cbPlay_Click(object sender, EventArgs e) { m_PPTobjectGui.set_video_time(0); m_PPTobjectGui.play(); m_timer.Interval = m_PPTobjectGui.get_interval_time() * 1000;//这里是2秒,m_PPTobjectGui.get_interval_time()等于2.

    m_timer.Enabled = true;//执行
                m_timer.AutoReset = false; //执行一次
    }

    //m_time的初始化写在界面的初始化中

    private System.Timers.Timer m_timer;
    m_timer = new System.Timers.Timer();
    m_timer.Elapsed += new ElapsedEventHandler(CheckUpdatetimer_Elapsed);

    整个过程是点击按钮后,执行函数cbPlay_Click,过了2秒后执行函数CheckUpdatetimer_Elapsed,函数CheckUpdatetimer_Elapsed中的locko是锁,防止线程重入。

    locko的定义也写在界面的初始化中, private object locko = new Object();

    C++中实现定时器的主要方式是:SetTimer。

    1.1 SetTimer简介

    UINT_PTR SetTimer(          

        HWND hWnd, 
        UINT_PTR nIDEvent,
        UINT uElapse,     //这里的延迟时间单位是毫秒,即1000毫秒 = 1秒
        TIMERPROC lpTimerFunc
    );

    功能:

          创建或设置一个定时器。

    参数:

        HWND hWnd, hWnd是和timer关联的窗口句柄,此窗口必须为调用SetTimer的线程所有;如果hWnd为NULL,没有窗口和timer相关联并且nIDEvent参数被忽略。 
        UINT_PTR nIDEvent, nIDEvent是timer的标识,为非零值;如果hWnd为NULL则被忽略;如果hWnd非NULL而且与timer相关联的窗口已经存在一个为此标识的timer,则此次SetTimer调用将用新的timer代替原来的timer。timer标识和窗口相关,两个不同的窗口可以拥有nIDEvent相同的tiemr。
        UINT uElapse, uElapse是以毫秒指定的计时间隔值。
        TIMERPROC lpTimerFunc, lpTimerFunc是一个回调函数的指针,俗称TimerFunc;如果lpTimerFunc为NULL,系统将向应用程序队列发送WM_TIMER消息;如果lpTimerFunc指定了一个值,DefWindowProc将在处理WM_TIMER消息时调用这个lpTimerFunc所指向的回调函数,因此即使使用TimerProc代替处理WM_TIMER也需要向窗口分发消息。

    其中TimerProc函数的原型如下:

    VOID CALLBACK TimerProc(
        HWND hwnd,
        UINT uMsg,
        UINT_PTR idEvent,
        DWORD dwTime
    );

    注意:定时器过了多长时间需要实现的功能都写到这个函数里面,并且格式固定,参数类型和函数的返回值类型一定固定,函数的名字可以自己命名;如果该函数是一个类的成员函数,则需要声明为static类型,同时里面所用的变量也需要声明为static。

    返回值:

          如果hWnd为NULL,返回值为新建立的timer的ID,如果hWnd非NULL,返回一个非0整数,如果SetTimer调用失败则返回0.

     通过上面的两个函数就可以创建一个时间定时器,如果想要结束时间定时器,可以通过KillTimer实现,

    KillTimer函数原型为:

    BOOL KillTimer(

        HWND hWnd,
        UINT_PTR uIDEvent
    );

    功能:

         销毁指定的定时器。

    参数:

        HWND hWnd, 与特定timer相关联的窗口句柄,
        UINT_PTR uIDEvent, 指定将要被销毁的timer的ID。如果hWnd不为NULL,则该参数与传递给SetTimer函数的nIDEvent相同;如果hWnd为NULL,则该参数与SetTimer函数的返回值相同。

    返回值:

       如果函数执行成功,返回非零值;如果执行不成功,返回零值。

    示例

       类PPTManager中声明TimerProc函数为:static void CALLBACK pause(HWND hWnd, UINT nMsg, UINT_PTR nIDEvent, DWORD dwTime);

       实现:

    void CALLBACK VRBase::PPTManager::pause(HWND hWnd, UINT nMsg, UINT_PTR nIDEvent, DWORD dwTime)
    {
        bool isTrue = KillTimer(NULL, m_TimerID);//执行一个后关闭该定时器
        if (m_timeObj != NULL && isTrue)
        {
            if (NetCollaboration::DataMonitor::Get()->isConnect())
            {
                NetCollaboration::DataMonitor::Get()->saveStateForNetCorp("%actn%ndID%order", NetCollaboration::objGuiVideo, m_timeObj->getID(), "objectGuiVideoPause");
            }
            else
            {
                VRNet::NodeSyncker::Get()->SetObjectGuiPause(m_timeObj);
            }
        }
    }

    其中,m_TimerID为定时器的返回值。

    定义的SetTimer为:m_TimerID = SetTimer(NULL, 3, delayTime, (TIMERPROC)pause);

    因为没有窗口,所以第一个参数为null,第二个参数在这里无用,第三个参数为延迟时间,第四个参数为过了delayTime后执行的操作,m_TimerID为返回值,使用KillTimer函数时,需要使用这个返回值。

    如果有窗口绑定的话,第一个参数不能为NULL,应该为窗口的句柄,函数的返回值为第二个参数,在使用KillTimer终止一个时间定时器的时候,第一个参数也应该是窗口的句柄,第二个参数为SetTimer中的

    第二个参数。

    注意:m_TimerID为Static,m_timeObj也为Static类型。

    以上是我最近使用定时器的一些总结,后面如果还有其他更好的方法,会在添加。

       

       

  • 相关阅读:
    记录此刻的感受(2018年8月26日19:44)
    提高工作效率
    VS C++项目报错warning C4199: ……use /Zc:twoPhase-
    dll加载遇到的问题
    记录xerces使用(VS2017 C++)
    vs编译应用程序不依赖运行vs环境
    [Locked] Binary Tree Vertical Order Traversal
    [Locked] Group Shifted Strings
    [Locked] Graph Valid Tree
    [Locked] Flatten 2D Vector
  • 原文地址:https://www.cnblogs.com/pengjun-shanghai/p/6422775.html
Copyright © 2011-2022 走看看