C# - 在计算需要更多时间时关闭控制台应用程序

时间:2016-02-28 21:51:11

标签: c# console

我写的应用程序每分钟都在重复执行某项任务。问题是有时候(内部计算(因为CPU忙或因为任何原因)花费超过50秒,然后我必须关闭应用程序。"独立应用程序的应用程序监视器将再次打开"所以这不是问题。我实现了看门狗,可以告诉我时间是否结束然后关闭我的应用程序。 我的问题是我是否正确地做到了。我测试了这个解决方案已经有一段时间了,看起来工作正常。

主程序

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AppTimer
{
    class Program
    {
        public static appScheduler ap = new appScheduler();
        static void Main(string[] args)
        {
            Console.WriteLine("Press ESC to stop");
            while (ap.getWatchDogSeconds() < 55)
            {
                if (Console.KeyAvailable)
                {
                    if (Console.ReadKey(true).Key == ConsoleKey.Escape)
                    {
                        break;
                    }
                }
                Thread.Sleep(100);
            }
            Console.WriteLine("Watchdog Fired ....sw finished !!");
            Thread.Sleep(2000);
        }

        /// <summary>
        /// Emulation of long calculation process
        /// </summary>
        public static void doJob()
        {
            Console.Clear();
            Thread.Sleep(5000);
            Console.WriteLine("Busy...");
            Console.WriteLine("WatchDog Seconds : " + ap.getWatchDogSeconds());
            ap.setWatchDogSeconds(40);
            Console.WriteLine("Waiting longer than normal...");
            Console.WriteLine("WatchDog Seconds : " + ap.getWatchDogSeconds());
            Thread.Sleep(5000);           
            Console.WriteLine("Maybe sth is down !! or too busy");
            Console.WriteLine("WatchDog Seconds : " + ap.getWatchDogSeconds());
            while (true)
            {
                Thread.Sleep(200);
            }
        }
    }
}

在appScheduler类下面:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AppTimer
{
    public class appScheduler
    {
        static readonly object _lockerWD = new object();
        static int minutes = 0;
        static int seconds = 50;
        static int days = 0;
        static int hours = 0;
        private static Task calculationsTask;
        private int watchDogSeconds = 0;
        private int maxSecondsForWatchdog = 50;

        public appScheduler()
        {
            startTimer();
            startWatchdogTimer();
        }

        private void ExecuteSeconds()
        {
            if (seconds == 0)
            {
                executeRepeatdTask();
            }
            calculateTime();
            showTimerScreen();
        }

        private void executeRepeatdTask()
        {
            calculationsTask = Task.Factory.StartNew(() =>
                Program.doJob());
        }

        public void startTimer()
        {
            var timer = new System.Threading.Timer((e) =>
            {
                ExecuteSeconds();
            }, null, 0, 1000);
        }

        public void startWatchdogTimer()
        {
            var timer = new System.Threading.Timer((e) =>
            {
                ExecuteSecondsWatchDog();
            }, null, 0, 1000);
        }

        private void ExecuteSecondsWatchDog()
        {
            Trace.WriteLine("Current amount of WD Seconds : " + watchDogSeconds);
            increaseWatchDogSeconds();
        }

        private void showTimerScreen()
        {
            if ((calculationsTask == null) || (calculationsTask.IsCompleted == true))
            {
                //making watchdog zero if time is running and we are showing it!!
                Console.Clear();
                Console.WriteLine("This is software v1.2");
                Console.WriteLine(String.Format("Current execution time : {0} days : {1} hours : {2} : minutes : {3} seconds",
                        days, hours, minutes, seconds));
                Console.WriteLine("WatchDog Seconds : " + watchDogSeconds);
                setWatchDogSeconds(0);
            }
        }

        private void calculateTime()
        {
            seconds++;
            if (seconds > 59)
            {
                seconds = 0;
                minutes++;
                if (minutes > 59)
                {
                    minutes = 0;
                    hours++;
                    if (hours > 23)
                    {
                        hours = 0;
                        days++;
                    }
                }
            }
        }

        public int getMinutes()
        {
            return minutes;
        }
        public int getWatchDogSeconds()
        {
            return watchDogSeconds;
        }
        public void setWatchDogSeconds(int seconds)
        {
            Monitor.Enter(_lockerWD);
            watchDogSeconds = seconds;
            Monitor.Exit(_lockerWD);
        }

        public void increaseWatchDogSeconds()
        {
            var seconds = getWatchDogSeconds();
            setWatchDogSeconds(seconds += 1);
            if (seconds > maxSecondsForWatchdog)
            {
                Trace.WriteLine(string.Format("More than {0} seconds!", maxSecondsForWatchdog)); ;
                Environment.Exit(0);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:-1)

我每天都会做大量的工作流程类型的任务。我曾经试图像过去那样开始工作。我使用Thread.Sleep的唯一一次是在测试环境中模拟一些长时间运行的进程。我会研究使用SetTimer。在循环中使用Thread.Sleep也不会给你准确的结果。现在,正如所说,保持这种运行将是棘手的。

如果您拥有SQL服务器并且可以在SSIS包中设置调用,那么最终定期开始工作是轻而易举的。特别是如果您正在尝试在Web应用程序中执行此操作,该应用程序可能会在一段时间后停止运行。祝你好运