重置System.Timers.Timer以防止Elapsed事件

ted*_*ski 5 c# asp.net static timer

我试图使用Timer触发事件来通过网络发送数据.我创建了一个简单的类来进行调试.基本上我有一个List<string>我想发送.我希望发生以下情况:

  1. 添加字符串 List
  2. 开始Timer10秒钟
  3. List之前添加第二个字符串Timer.Elapsed
  4. 重启Timer10秒钟.

到目前为止我有这个:

public static List<string> list;
public static Timer timer;
public static bool isWiredUp = false;

public static void Log(string value) {
    if (list == null) list = new List<string>();
    list.Add(value);

    //this does not reset the timer, elapsed still happens 10s after #1
    if (timer != null) {
        timer = null;
    }

    timer = new Timer(10000);
    timer.Start();
    timer.Enabled = true;
    timer.AutoReset = false;

    if (!isWiredUp) {
        timer.Elapsed += new ElapsedEventHandler(SendToServer);
        isWiredUp = true;
    }
}

static void SendToServer(object sender, ElapsedEventArgs e) {
    timer.Enabled = false;
    timer.Stop();
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Ser*_*rvy 11

您可以使用Stop函数后面的Start函数来"重启"计时器.使用它可以创建Timer第一次创建类时,在那时连接Elapsed事件,然后在添加项时调用这两种方法.它将启动或重新启动计时器.请注意,调用Stop尚未启动的计时器不会执行任何操作,它不会引发异常或导致任何其他问题.

public class Foo
{
    public static List<string> list;
    public static Timer timer;
    static Foo()
    {
        list = new List<string>();
        timer = new Timer(10000);
        timer.Enabled = true;
        timer.AutoReset = false;
        timer.Elapsed += SendToServer;
    }

    public static void Log(string value)
    {
        list.Add(value);
        timer.Stop();
        timer.Start();
    }

    static void SendToServer(object sender, ElapsedEventArgs e)
    {
        //TODO send data to server

        //AutoReset is false, so neither of these are needed
        //timer.Enabled = false;
        //timer.Stop();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,List您可能不希望使用它而非使用它BlockingCollection<string>.这有几个优点.首先,Log如果从多个线程同时调用,这些方法将起作用; 因为多个并发日志可能会破坏列表.这也意味着SendToServer可以在添加新项目的同时将项目从队列中取出.如果您使用a List,则需要对lock列表进行所有访问(这可能不是问题,但不是那么简单).