定时器

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类型。

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

   

   

 

posted on 2017-02-21 10:16  !!-阳光-!!  阅读(267)  评论(0编辑  收藏  举报

导航