【问题标题】:Timer callback is still running after instance isn't reachable无法访问实例后,计时器回调仍在运行
【发布时间】:2015-06-17 20:57:15
【问题描述】:

离开作用域后,线程TimerTest.exe!TimerTest.TimeClass.Callback(object state) 仍在运行。

避免此类运行线程的最佳做法是什么?

  1. IDisposable 类 TimerClass?
  2. 添加析构函数?
  3. 实现一个方法来处理定时器?

小样本:

using System;
using System.Threading;

namespace TimerTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            // just a scope
            {
                var timerClass = new TimerClass(1);
            }

            Console.ReadKey();
        }
    }

    internal class TimerClass
    {
        private Timer timer;

        public TimerClass(int i)
        {
            this.timer = new Timer(Callback, i, 500, 1000);
        }

        private void Callback(object state)
        {
            Console.Out.WriteLine("Timer: " + state);
        }
    }
}

【问题讨论】:

  • 要使其成为正确的测试,请在 Readkey 之前添加 GC.Collect()。但是仍然可能存在调试/发布差异,并且很少有保证。

标签: c# multithreading timer garbage-collection weak-references


【解决方案1】:

当您在主线程中启动计时器时,实际上会在线程池中启动一个新线程。

如果您将实现 IDispoable 并使用以下方法创建计时器类:

(using var timerClass = new TimerClass(1))
{
    your code here....
}

在 dispose 方法中,您需要从计时器中删除引用,以便 GC 收集此对象,因为不会再有对该对象的引用。

对我来说最好的方法是使用 IDispoe 和 using...

您也可以在达到点击数时在回调方法中清除计时器的引用。

关于弱引用 - 我不确定这种情况是否符合定义

【讨论】:

  • using(){} 通常不适用于计时器。将生命周期限定为方法是非常罕见的。在这个例子中它会起作用,但这是人为的。
  • @HenkHolterman 是的,你是对的.. 但我的意思是在 TimerClass 中配置 Timer
猜你喜欢
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 2019-10-21
  • 1970-01-01
相关资源
最近更新 更多