简体   繁体   English

如何立即触发 timer.Elapsed 事件

[英]How to fire timer.Elapsed event immediately

I'm using the System.Timers.Timer class to create a timer with an Timer.Elapsed event.我正在使用System.Timers.Timer类来创建一个带有Timer.Elapsed事件的计时器。 The thing is the Timer.Elapsed event is fired for the first time only after the interval time has passed.问题是Timer.Elapsed事件仅在间隔时间过去后第一次被触发。

Is there a way to raise the Timer.Elapsed event right after starting the timer ?有没有办法在启动计时器后立即引发Timer.Elapsed事件?

I couldn't find any relevant property in the System.Timers.Timer class.我在System.Timers.Timer类中找不到任何相关属性。

Just call the Timer_Tick method yourself.只需自己调用Timer_Tick方法。


If you don't want to deal with the Tick callback method's parameters, then just put the code that was in your Timer_Tick into another method, and call that from the Timer_Tick and from just after the Timer.Start() call如果您不想处理 Tick 回调方法的参数,则只需将Timer_Tick的代码放入另一个方法中,然后从 Timer_Tick 和Timer.Start()调用之后调用它


As pointed out by @Yahia, you could also use the System.Threading.Timer timer, which you can set to have an initial delay to 0. Be aware though, that the callback will run on a different thread, as opposed to the callback on the Windows.Forms.Timer which runs on the UI thread.正如@Yahia 所指出的,您还可以使用System.Threading.Timer计时器,您可以将其设置为初始延迟为 0。但请注意,回调将在不同的线程上运行,而不是回调在 UI 线程上运行的Windows.Forms.Timer上。 So if you update any UI controls using the System.Threading.Timer (without invoking correctly) it'll crash.因此,如果您使用System.Threading.Timer更新任何 UI 控件(未正确调用),它将崩溃。

我只是用空参数调用了**ElapsedEventHandler**

I know this answer is late but if you want your System.Timers.Timer to be fired within 100ms (default interval) then you could simply just initialize the Timer object without a specified interval, then set the interval within the called function to whatever you like.我知道这个答案来晚了,但是如果您希望System.Timers.Timer在 100 毫秒(默认间隔)内触发,那么您可以简单地初始化Timer对象而没有指定的间隔,然后将被调用函数中的间隔设置为您想要的任何值像。 Here is an example of what I use in my Windows Service:这是我在 Windows 服务中使用的示例:

private static Timer _timer;

protected override void OnStart(string[] args)
{
    _timer = new Timer(); //This will set the default interval
    _timer.AutoReset = false;
    _timer.Elapsed = OnTimer;
    _timer.Start();
}

private void OnTimer(object sender, ElapsedEventArgs args)
{
    //Do some work here
    _timer.Stop();
    _timer.Interval = 50000; //Set your new interval here
    _timer.Start();
}

not sure about System.Timers.Timer but try不确定System.Timers.Timer但试试

System.Threading.Timer T = new System.Threading.Timer(new TimerCallback(DoSomething), null, 0, 30000);

This starts immediately (0 milliseconds for first run, 30000 milliseconds for subsequents runs)...这会立即开始(第一次运行为 0 毫秒,后续运行为 30000 毫秒)...

see
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
http://msdn.microsoft.com/en-us/library/2x96zfy7.aspx http://msdn.microsoft.com/en-us/library/2x96zfy7.aspx

Task.Run(() =>
{
   Timer_Elapsed(null, null);
});

After Timer creation/configuration, worked fine for me...定时器创建/配置后,对我来说工作正常......

For the first time, the timer will start after 1 second.第一次,计时器将在 1 秒后启动。 After that, its interval will be changed to every 30 seconds or whatever...之后,它的间隔将更改为每 30 秒或其他什么......

    //main function    
    Timer timer = new Timer(1000);   //initial start after 1 second
        timer.Elapsed += new ElapsedEventHandler(TimerElapsedMethod);
        timer.Start();            
    }
    private void TimerElapsedMethod(object sender, ElapsedEventArgs e) 
    {
        Timer timer = (Timer)sender; // Get the timer that fired the event
        timer.Interval = 30000;      // Change the interval to whatever
        .
        .
        .
    }

If you want to be able to raise the event whenever you want (not only just at the moment you start the timer), you can encapsulate a timer in your own MyTimer class.如果您希望能够随时引发事件(不仅仅是在您启动计时器的那一刻),您可以在您自己的 MyTimer 类中封装一个计时器。 This class exposes the original Timer methods and properties.此类公开原始 Timer 方法和属性。 Furthermore I added an event with explicit add and remove.此外,我添加了一个带有显式添加和删除的事件。 In this way whenever you add a delegate to the event this is added to both the private MyTimer's event and to the original timer Elapsed event.通过这种方式,无论何时向事件添加委托,都会将其添加到私有 MyTimer 事件和原始计时器 Elapsed 事件中。 This means that the timer triggers Elapsed in the usual way, but you can manually trigger the event calling RaiseElapsed (this should sound much simpler looking at the code).这意味着计时器以通常的方式触发 Elapsed,但您可以手动触发调用 RaiseElapsed 的事件(这听起来应该更简单查看代码)。

public class MyTimer
{
    Timer t = new Timer();
    event ElapsedEventHandler timerElapsed;

    public event ElapsedEventHandler Elapsed
    {
        add
        {
            t.Elapsed += value;
            timerElapsed += value;
        }
        remove
        {
            t.Elapsed -= value;
            timerElapsed -= value;
        }
    }

    public double Interval
    {
        get
        {
            return t.Interval;
        }
        set
        {
            t.Interval = value;
        }
    }

    public void Start()
    {
        t.Start();
    }

    public void Stop()
    {
        t.Stop();
    }

    public void RaiseElapsed()
    {
        if (timerElapsed != null)
            timerElapsed(null, null);
    }
}

I have implemented in VB.NET with AddHandler我已经在 VB.NET 中使用 AddHandler 实现了

Public Class clsMain Inherits ServiceBase

Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
gTimer.Interval = 1000  
gTimer.Enabled = True
AddHandler gTimer.Elapsed, AddressOf gTimer_Elapsed
End Sub

'When the timer is elapsed this event will be fired

Protected Sub gtimer_Elapsed(ByVal source As Object, ByVal e As ElapsedEventArgs)
'Stop the timer and do some work
gTimer.Stop()
'Custom code
'Here
'Start to raise the elapsed event again
gTimer.Start()
End Sub
End Class

I'm not a pro so take this with a pinch of salt but it works.我不是专业人士,所以加一点盐,但它有效。 I created a function and instead of putting my code into the timer sub I put it into the function.我创建了一个函数,而不是将我的代码放入计时器子中,而是将其放入函数中。 Then I merely called the function when I wanted it (in my case on page load) and then the timer code would fire at the interval times and simply call the function in the timer sub code.然后我只是在需要时调用该函数(在我的情况下是在页面加载时),然后计时器代码将在间隔时间触发,并在计时器子代码中简单地调用该函数。

Here is the easy answer .这是简单的答案 (Assuming you're using a Windows form) (假设您使用的是 Windows 窗体)

After dragging your timer control to your form, set the enabled property to true, and the Interval property to whatever you want the initial value to be.将计时器控件拖到窗体上后,将 enabled 属性设置为 true,将 Interval 属性设置为您想要的初始值。 (100 is the default and will start the tick event immediately) (100 是默认值,会立即启动滴答事件)

在此处输入图片说明

Then within your tick event, simply check the value of the Interval property.然后在您的滴答事件中,只需检查 Interval 属性的值。 If it is not your desired value, set it.如果它不是您想要的值,请设置它。 It's that simple .就是这么简单 The same can be accomplished in your C# code if creating a timer on the fly.如果动态创建计时器,也可以在 C# 代码中完成相同的操作。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM