简体   繁体   English

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

[英]Is my Timer causing my application to hang?

I've been scratching my head for days about this problem. 我已经为这个问题about了好几天。 I'm trying to get a timer that restarts the application every 50s. 我正在尝试获取一个计时器,该计时器每50秒重新启动一次应用程序。 The code basically fetches database items every 50s and does something. 该代码基本上每隔50s提取一次数据库项,然后执行某些操作。 However it seems to hang overnight when there has been a long period of inactivity. 但是,如果长时间不活动,它似乎会挂在一夜之间。 I've just shown a skeleton of the code below. 我刚刚显示了下面的代码框架。 In the code also theres's a connection to a mysql db, rest hhtpwebrequest, and a ssh using renci.ssh to get to another computer. 在代码中,还存在与mysql db,rest hhtpwebrequest和使用renci.ssh到另一台计算机的ssh的连接。 All these are closed properly. 所有这些都已正确关闭。

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();

        }

Somewhere towards the end of my code i also used Console.ReadLine(); 在代码结尾处,我还使用了Console.ReadLine();。 to hold the program open. 使程序保持打开状态。 Is there a reason why this should hang after a period of inactivity? 一段时间不活动后,为什么应该挂起它? I have a suspicion it's my code but it may also be the linux box? 我怀疑这是我的代码,但也可能是linux系统吗? Will post the whole code if need be. 如有需要,将发布整个代码。 Thank you so much for all your help. 非常感谢您的帮助。 Cheers. 干杯。

I guess you are trying to do this: 我想您正在尝试这样做:

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
}

I think that by blocking in the callback you'll eventually use up the threadpool. 我认为通过阻止回调,您最终将耗尽线程池。

From MSDN : MSDN

The method specified for callback should be reentrant, because it is called on ThreadPool threads. 为回调指定的方法应该是可重入的,因为它是在ThreadPool线程上调用的。 The method can be executed simultaneously on two thread pool threads if the timer interval is less than the time required to execute the method, or if all thread pool threads are in use and the method is queued multiple times. 如果计时器间隔小于执行该方法所需的时间,或者所有线程池线程都在使用中并且该方法多次排队,则可以在两个线程池线程上同时执行该方法。

In your example the time to execute the callback is taking indefinitely long as it is blocking while waiting for user input. 在您的示例中,执行回调的时间是无限长的,因为它在等待用户输入时被阻塞。

If you want to perform such computation, I suggest you to have one independent thread that will contain a Sleep(50000) call inside. 如果要执行这样的计算,建议您使用一个独立的线程,该线程内部将包含一个Sleep(50000)调用。 The reason is that if your computation takes more than 50 seconds you might end up with an overhead. 原因是,如果您的计算花费超过50秒,则可能会产生开销。

So in your thread measure the start time, do your computation, measure the end time, then compute the computation time and do a sleep of 50 seconds - "computation time". 因此,在您的线程中测量开始时间,进行计算,测量结束时间,然后计算计算时间并进行50秒的睡眠-“计算时间”。 Ensure that this number is positive and put a 10 second minimum sleep in order to let some slack to the other tasks if the computation was longer than 40 seconds. 如果计算时间超过40秒,请确保此数字为正数,并至少睡眠10秒钟,以使其他任务有所放松。

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

then: 然后:

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() does not have the ReadLine call. ** doWork()没有ReadLine调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM