计时器类在程序结束前未触发 [英] Timer Class not Firing before End of Program

查看:55
本文介绍了计时器类在程序结束前未触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图修改 Sriram Sakthivel 在这里发布的代码块:

So i've attempted to modify the code block posted by Sriram Sakthivel here:

C#:如何开始一个线程具体时间

public class Program
{
    static Boolean checkIn = false;

    public static void checkInCycle()
    {
        checkIn = SynchronousSocketClient.StartClient();

        if(checkIn == false)
        {
            // Use TimeSpan constructor to specify:
            // ... Days, hours, minutes, seconds, milliseconds.
            TimeSpan span = new TimeSpan(00, 00, 30);

            //SetUpTimer(span);
            DateTime current = DateTime.Now;
            TimeSpan triggerTime  = current.TimeOfDay + span;

            SetUpTimer(triggerTime);
        }
        if(checkIn == true)
        {

            //Do some processing 
        }



    }

    public static void SetUpTimer(TimeSpan alertTime)
    {
        //DateTime current = DateTime.Now;
        //TimeSpan timeToGo = alertTime - current.TimeOfDay;

        TimeSpan timeToGo = alertTime;
        Console.WriteLine("Checking in at: " + timeToGo);

        if (timeToGo < TimeSpan.Zero)
        {
            return; //time already passed
        }
        System.Threading.Timer timer = new System.Threading.Timer(x =>
        {
            Console.WriteLine("Running CheckIn Cycle");
            checkInCycle();

        }, null, timeToGo, Timeout.InfiniteTimeSpan);

    }

    public static int Main(String[] args)
    {
        checkInCycle();

        Console.WriteLine("End of Program Reached");
        Console.ReadLine();

        return 0;

    }
}

然而,我没有指定确切的运行时间,而是尝试在当前时间上增加 30 分钟,以尝试使客户端服务在尝试再次连接之前保持活动 x 分钟.现在,为了简单/测试起见,如果它无法连接到服务器,我将它设置为每 30 秒运行一次 checkInCycle.

However instead of specifying an exact time to run at, i've attempted to add 30 mins onto the current time in an attempt to make a client service that will remain alive for x amount of minutes before attempting to connect again. Right now, for simplicity/testing sake i have it set to run checkInCycle every 30 seconds if it cant connect to the server.

首先检查 SynchronousSocketClient.StartClient();如果服务器关闭,则成功返回 false,并将进入 if(checkIn == false) 循环 - 但是,在设置计时器后,它继续处理主循环的其余部分,并在最后等待而不触发和重新安排一个计时器.

Upon first check SynchronousSocketClient.StartClient(); succesfully returns false if the server is down, and will enter the if(checkIn == false) loop - however, after setting up a timer it moves on to process the rest of the main loop, and waits at the end without triggering and rescheduling a timer.

关于为什么会发生这种情况的任何想法?另外我知道我可以在重新检查之前让主线程休眠 x 分钟,但是客户端可能会休眠长达几个小时,因此我听说计时器效率更高,是这种情况吗?

Any ideas as to why this is happening? Also I understand i could just sleep the main thread for x amount of minutes before rechecking again, but the client could be asleep for up to several hours and because of this i have heard that timers are more efficient, is this the case?

推荐答案

发生这种情况是因为在执行 main() 方法结束时,您丢失了对 System.Threading.Timer 的引用代码>.new System.Threading.Timer 调用在等待运行其代码时不会阻塞主线程.

This is happening because at the end of your execution of the main() method you are losing the reference to your System.Threading.Timer. The new System.Threading.Timer call does not block the main thread while it waits to run its code.

在上述参考(备注下的第二个注释)中,文档解释了必须维护一个参考(与所有托管代码一样),以免被垃圾收集器处理.

In the above reference (second note under Remarks), the documentation explains that a reference must be maintained (as with all managed code) for it not to be disposed of by the Garbage Collector.

只要您在使用 Timer,就必须保留对它的引用.与任何托管对象一样,当没有对 Timer 的引用时,它会受到垃圾回收的影响.Timer 仍然处于活动状态的事实并不能阻止它被收集.

As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.

保持这个简单程序的方法是使用 System.Threading.Monitor 并在 checkInCycle() 之后直接执行 Wait()main() 函数中的函数调用.然后 Pulse() 当你想继续时.

The way you can keep this simple program is if you use a System.Threading.Monitor and perform a Wait() directly after the checkInCycle() function call in the main() function. Then Pulse() when you want to proceed.

如果您对执行异步调用或在多线程环境中操作的任何更深入的主题感到好奇,您可能想进一步阅读线程同步或并发.

You may want to read up on thread synchronization or concurrency further if you are curious about any more in-depth topics on performing asynchronous calls or operating in a mutli-threaded environment.

*为澄清而编辑.

这篇关于计时器类在程序结束前未触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆