2016-02-28 39 views
0

我写了每分钟重复执行一些任务的应用程序。问题是,有时(内部计算(因为CPU很忙或者因为任何原因)需要超过50秒,那么我必须关闭应用程序。“独立应用程序的应用程序监视器将再次打开它”,所以这不是问题。我实现了看门狗,它可以告诉我时间是否完成,然后关闭我的应用程序 而我的问题是,如果我正确地做到了这一点,我测试这个解决方案一段时间,它看起来像工作正常。主程序C# - 计算需要更多时间时关闭控制台应用程序

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); 
      } 
     } 
    } 
} 
+0

那么问题是什么?你说它行得通... ...? –

+1

如果您想每隔1分钟运行一次应用程序,则可能需要查看“任务计划程序”。您可以将应用程序配置为关闭并每分钟重新开始一次。 –

+0

乔纳森卡罗尔 - 问题是如果除了工作好,后面的想法是好的。 inquisitive_mind - 嗯,这可能是一个好主意,而不是内部复杂的逻辑。我应该杀了应用程序,如果它会工作太长,并再次启动它。 –

回答

-1

我每天都在做大量的工作流类型任务。我试图按照过去的方式开展工作。我使用Thread.Sleep的唯一时间是在测试环境中模拟一些长时间运行的进程。我会考虑使用SetTimer。在循环中使用Thread.Sleep也不会给你准确的结果。这就是说,保持这种运行方式将会非常棘手。

如果你有一个SQL服务器,并且可以在SSIS包中设置调用,最终定期开始工作是一件轻而易举的事情。特别是如果你正试图在一段时间内停止运行的Web应用程序中执行此操作。好运

相关问题