定时器范围和适当的处理

时间:2018-05-02 22:21:46

标签: c#

所以我正在使用System.Timers.Timer对象在任务调度程序上工作以在任务之间等待。为了使用这个计时器,我将它放在实例化的静态(扩展)方法中并仅在那里使用它。我的问题是,在静态方法结束时是否妥善处理,还是我需要做更多的事情?这就是我正在使用的。

public static void Use<T>(this T o, Action<object> work) => work(o);

private void RunLoop()
{
    while (!Stop)
    {
        try
        {
            //Method 1
            new System.Timers.Timer((task.NextRun - DateTime.Now).TotalMilliseconds).Use(timer => {
                timer.Elapsed += (s, e) => {
                    new Thread(new ThreadStart(RunProc)) {
                        Name = task.Title,
                        IsBackground = true
                    }.Start();
                };
                timer.AutoReset = false;
                timer.Start();
            });

            //Method 2
            using (var timer = new System.Timers.Timer((task.NextRun - DateTime.Now).TotalMilliseconds))
            {
                timer.Elapsed += (s, e) =>
                {
                    new Thread(new ThreadStart(RunProc))
                    {
                        Name = task.Title,
                        IsBackground = true
                    }.Start();
                };
                timer.AutoReset = false;
                timer.Start();
            }

        } catch(SqlException ex)
        { //Omitted for size }
        catch (Exception ex)
        { //Omitted for size }
    }
}

方法1是否会正确处理我的计时器,或者我是否必须调用dispose或处理GC的using语句来获取它?从我一直在阅读的大多数对象中,当它们超出使用中的lambda调用范围时,它们将获得GC。但显然Timers的不同之处在于它们连接到一些未经管理的资源,这些资源可能会导致它们持续存在,即使您希望它们得到清理,例如说超出范围。

2 个答案:

答案 0 :(得分:0)

虽然技术上不需要,但应始终正确处理定时器(就像从IDisposable继承的几乎所有东西一样)。如果您不处理计时器会发生什么?它们将一直存在,直到垃圾收集检测到它们不再可达,然后它们将被最终确定(它应该自动执行与处理它们相同的事情,但它不是那么有效)。

在您的方法2中,计时器可能不会触发,因为它会在创建后立即处理(在经过的Elapsed委托之前)。

所以,问题就变成了,什么时候应该处理掉计时器?那么,这取决于它的使用方式。如果您只使用它来执行一次该小代码块,则可以在执行结束时将其丢弃。如果它不止一次触发,你需要让一些其他外部所有者在不再需要它时处理它。

答案 1 :(得分:0)

为了关闭,我最终为每个动作创建了一个计时器列表,然后只需更新间隔,并根据需要回收它们。然后添加一个特定的功能,以在停止服务时正确停止和处理所有这些功能。一旦同时安排了2个任务,我上面的设置就会失败,所以它不会以任何方式工作。通过这种新的方式,我不必担心它,因为它们要么无限期地回收,要么被专门处理掉。