定时器范围界定和正确处置

  • 本文关键字:范围 定时器 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 或处理 using 语句才能让 GC 获取它?根据我对大多数对象的阅读,当它们超出使用中的 lambda 调用范围时,它们将被 GC'ed。但显然计时器的不同之处在于它们连接到一些非托管资源,即使您期望它们会被清理,例如超出范围,也可能导致它们仍然存在。

尽管在技术上不是必需的,但计时器应始终正确配置(就像从 IDisposable 继承的几乎所有内容一样(。 如果不处理计时器会发生什么? 它们将累积,直到垃圾回收检测到它们不再可访问,然后它们将被最终确定(这应该自动执行与处置它们相同的操作,但它的效率不高(。

在方法 2 中,计时器可能永远不会触发,因为它将在创建后立即释放(在已用委托运行之前(。

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

对于闭包,我最终为每个操作创建了一个计时器列表,然后只是更新间隔,并根据需要回收它们。然后添加了一个特定函数,以便在停止服务时正确停止和处置所有这些。一旦同时安排了 2 个任务,我上面的设置就会失败,所以无论哪种方式都不起作用。有了这种新方法,我不必担心,因为它们要么被无限期回收,要么被专门处理。

最新更新