C# - 创建setInterval / clearInterval函数

时间:2017-08-09 09:22:04

标签: c#

我是C#的新手,并尝试创建一个setIntervalclearInterval函数,该函数与javascript中的函数完全相同。

我主要是为了练习和学习C#中可以做什么而不是。

的setInterval

要求:创建一个新的计时器并将其返回,同时在给定的时间间隔内反复运行匿名函数或预定义函数。

    Timer setInterval(Func<int> myMethod, int intervalInMs)
    {
        var timer = new Timer();
        timer.Start();

        while (true) {   //probably a infinite loop
            if (timer.ElapsedMilliseconds >= intervalInMs)
            {

                myMethod();
                timer.Restart();
            }
        }

        return timer;  //Code does never reach this part obviously because of the while loop
    }

clearInterval

要求:停止计时器。

    void clearInterval(Timer timer)
    {
        timer.Stop();
    }

计划使用

    Timer myTimer = setInterval(delegate {
        MessageBox.Show(
            "test",
            "test",
            MessageBoxButtons.OK,
            MessageBoxIcon.Warning
        );

        return 1;
    }, 5000);


    //somewhere in code...

    clearInterval(myTimer);

如何通过使用事件来解决这个问题呢?

2 个答案:

答案 0 :(得分:2)

.Net框架提供至少三种不同的计时器 - System.Timers.TimerSystem.Threading.TimerSystem.Windows.Forms.Timer
System.Diagnostic.Stopwatch不是计时器,不应该用作计时器。它仅衡量Start()Stop()之间经过的时间。

我建议使用.Net框架提供的其中一个计时器,而不是重新发明轮子。

更新

好吧,既然你坚持, 这是一个简单的实现不适用于生产代码,因为它很容易用它创建内存泄漏:

public static class Interval
{
    public static System.Timers.Timer Set(System.Action action, int interval)
    {
        var timer = new System.Timers.Timer(interval);
        timer.Elapsed += (s, e) => {
            timer.Enabled = false;
            action();
            timer.Enabled = true;
        };
        timer.Enabled = true;
        return timer;
    }

    public static void Stop(System.Timers.Timer timer)
    {
        timer.Stop();
        timer.Dispose();
    }
}

You can see a live demo on rextester.

答案 1 :(得分:-1)

我设法通过使用事件来解决它。它可能不是最好的解决方案,但正如我已经提到的,我是C#初学者。

示例:

此示例每隔5000毫秒显示一个消息框,在三个消息框之后更改间隔,在10个框中显示间隔被清除。您也可以按按钮停止间隔。

enter image description here

using System;
using System.Windows.Forms;

namespace Intervals
{
    public partial class Form1 : Form
    {
        Interval ival1 = new Interval();
        private int _A;

        public int A
        {
            get { return _A; }
            set {
                _A = value;

                if (value == 3) {
                    if (ival1 != null) {
                        MessageBox.Show(
                            "changeInterval Triggered",
                            A.ToString(),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Warning
                        );
                        ival1.changeInterval(1000);
                    }
                }

                if (value >= 10)
                {
                    if (ival1 != null)
                    {
                        MessageBox.Show(
                            "clearInterval Triggered",
                            A.ToString(),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Warning
                        );
                        ival1.clearInterval();
                    }
                }
            }
        }

        public Form1()
        {
            InitializeComponent();

            int interval = 5000;

            ival1.setInterval(delegate {
                A++;

                MessageBox.Show(
                    A.ToString(),
                    "A",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning
                );
            }, interval);
        }

        private void stopInterval_Click(object sender, EventArgs e)
        {
            ival1.clearInterval();
        }
    }
}

我创建了一个新类Interval,这是该程序运行所必需的。

using System;

namespace Intervals
{
    public class Interval
    {
        private System.Timers.Timer timer;
        private Action main;

        public Interval()
        {
            timer = new System.Timers.Timer();
        }

        public void setInterval(Action pAction, int interval)
        {
            if (interval <= 0) { interval = 100; }
            timer.Interval = interval;

            main = new Action(delegate{
                timer.Stop();
                pAction?.Invoke();
                timer.Start();
            });

            timer.Elapsed += (sender, e) => TimerEventProcessor(sender, e);
            timer.Start();
        }

        public void changeInterval(int interval)
        {
            timer.Stop();
            timer.Interval = interval;
            timer.Start();
        }

        public void clearInterval()
        {
            main?.EndInvoke(null);

            main = delegate
            {
                timer.Stop();
                timer.Dispose();
            };
        }

        public void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
        {
            main?.Invoke();
        }
    }
}

内存使用测试(260分钟):

enter image description here