关于这个问题,我几天都在摸不着头脑。我正在尝试获得一个每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盒子?如果需要,将发布整个代码。非常感谢您的帮助。欢呼声。
答案 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调用。