我的计时器导致我的应用程序挂起吗?

时间:2014-05-20 15:35:42

标签: c# timer

关于这个问题,我几天都在摸不着头脑。我正在尝试获得一个每50秒重启一次应用程序的计时器。代码基本上每50秒获取一次数据库项并执行某些操作。然而,当长时间不活动时,它似乎一夜之间就会挂起。我刚刚展示了下面代码的骨架。在代码中,还有一个与mysql db的连接,rest hhtpwebrequest和一个使用renci.ssh到另一台计算机的ssh。所有这些都正确关闭。

static void Main(string[] args)
        {
            Timer timer = new Timer(state => workDone(), null, 50000, 50000);
            workDone();
        }

        private static void workDone()
        {


        //Hold program open for next cycle
            Console.ReadLine();

        }

在代码结束的某处,我也使用了Console.ReadLine();保持程序开放。有一个原因,为什么这应该在一段时间不活动后挂起?我怀疑它是我的代码但它也可能是linux盒子?如果需要,将发布整个代码。非常感谢您的帮助。欢呼声。

2 个答案:

答案 0 :(得分:2)

我猜你是想这样做的:

private static Timer timer;

static void Main(string[] args)
{
    timer = new Timer(state => workDone(), null, 0, 50000);

    // Hold program open...
    Console.ReadLine();
}

private static void workDone()
{
    // Do work
}

我认为通过阻止回调,你最终会耗尽线程池。

来自MSDN

  

为回调指定的方法应该是可重入的,因为它是在ThreadPool线程上调用的。如果定时器间隔小于执行方法所需的时间,或者所有线程池线程都在使用且方法排队多次,则可以在两个线程池线程上同时执行该方法。

在您的示例中,执行回调的时间无限期,因为它在等待用户输入时阻塞。

答案 1 :(得分:1)

如果你想进行这样的计算,我建议你有一个独立的线程,里面会包含一个Sleep(50000)调用。原因是如果你的计算时间超过50秒,你可能最终会产生开销。

因此,在您的线程中测量开始时间,进行计算,测量结束时间,然后计算计算时间并进行50秒的睡眠 - "计算时间"。确保这个数字是正数并且最小睡眠时间为10秒,以便在计算时间超过40秒时让其他任务松弛。

Thread thread = new Thread(new ThreadStart(myThreadFunction)); thread.Start();

然后:

public void myThreadFunction()
{
    Stopwatch stopWatch = new Stopwatch();

    while(someCondition) { 
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();
        doWork();
        stopWatch.Stop();
        long elapsed = stopWatch.ElapsedMilliseconds;
        if(elapsed < 10000) elapsed = 10000;
        Thread.Sleep(elapsed);
    }
}

** doWork()没有ReadLine调用。