【问题标题】:How to preserve System.Threading.Timer when function is call again再次调用函数时如何保留 System.Threading.Timer
【发布时间】:2015-09-30 08:13:58
【问题描述】:

我正在做一个简单的 System.Threading.Timer 测试,因为我想在我的窗口服务中使用它。我面临的问题是当我再次调用 Timer 所在的函数时,现有的运行时间将消失,我该如何保留它?

类文件:-

namespace Worker
{
 public class ProcessingWork
 {
    public void testTimer()
    {
        DataTable WorkCheck = getNewWork(); // Get new work from Database if there is any
        foreach (DataRow dr in WorkCheck.Rows)
        {
            if (dr["IsNew"] == "true")
            {                   
                Timer JobTimer = new Timer(timer =>
                {
                    try
                    {
                        Console.WriteLine("id is " + Convert.ToInt32(dr["WorkID"]).ToString());
                        int WorkID = Convert.ToInt32(dr["WorkID"]);

                        if (WorkID != 0)
                        {
                            Console.WriteLine(DateTime.Now + " | Running " + WorkID);
                            ((Timer)timer).Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(999));
                        }                       
                    }
                    catch (Exception ex)
                    {
                        //Log
                    }
                });
                JobTimer.Change(0, 0);
            }
        }
    }
 }
}

主程序:-

class Program 
{
    static void Main(string[] args)
    {
        Thread[] WorkerThread = new Thread[1];
        ProcessingWork pw = new ProcessingWork();            
        WorkerThread[0] = new Thread(() =>
        {
            int i = 0;
            while (true)
            {
                Console.WriteLine("Running " + i);
                pw.testTimer();
                Thread.Sleep(10000);
                i++;
            }
        })
        {
            Name = "Test"
        };
        WorkerThread[0].Start();
}

我编写此代码的目的是允许每次重复。当我再次调用我的线程运行的函数并调用pw.tesTimer() 时,它将检查数据库是否需要处理任何新工作。如果有,它将为工作创建另一个计时器。

我面临的问题是,当我再次调用 pw.testTimer(); 时,所有正在运行的 Timer 都会停止并消失。我尝试不重新调用pw.testTimer(); 时间将像我设置的那样每 2 秒运行一次。

我需要的是创建计时器应该始终继续运行,当有新工作时,它只是添加另一个计时器。

【问题讨论】:

  • 如果需要存储多个计时器,则需要将计时器存储在类的字段或数组字段中。
  • @MatthewWatson 定时器应该在线程池中,它会一直着火
  • 如果这是真的,那么你就不会问这个问题了。如您所知,它不会继续触发,您的 JobTimer 变量不足以防止它被垃圾收集。它只是 testTimer() 方法的局部变量,该对象引用仅存在几纳秒。您可以通过将其设置为您的类的字段来“保留”它,以便 GC 可以继续看到它被使用。否则 System.Timers.Timer 存在的原因,它使用一个技巧来防止收集,只要它被启用。不要使用它。

标签: c# multithreading timer


【解决方案1】:

问题不是因为定时器行为,问题是因为每当WorkCheck表被编辑时,之前创建的定时器无法引用该值,因此定时器将中止。

例如在正在运行的 Timer Convert.ToInt32(dr["WorkID"]); //Value 1 中,因为我确实通过 DataTable WorkCheck = getNewWork(); 更新表当没有新数据来时,该行将为空,最终它将重写表,因此第一个计时器是引用值1 ,但现在的值为 0。因此它会导致正在运行的计时器中止。

我通过深度克隆 WorkCheck 解决了这个问题,计时器应该引用克隆表

来自

foreach (DataRow dr in GJobList.Rows)

 foreach (DataRow dr in GJobList.DeepClone().Rows)

感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2013-11-06
    • 1970-01-01
    • 2014-09-26
    • 2011-02-12
    相关资源
    最近更新 更多