[英]C# - Close console application when calculations take more time
I wrote app that is doing repeatedly some task every minute. 我编写的应用每分钟重复执行一些任务。 Problem is that sometimes ( inner calculations ( because CPU was busy or because of any reasons) take more than 50 seconds, then I have to close app. "App monitor that is independent application will turn it on again" so that is not a problem. I implemented watchdog which can tell me if time is finished and then shut down my app. And my question is if I'm doing it correctly. I test this solution for some time and it looks like working ok. 问题是有时(内部计算(由于CPU忙或由于任何原因)需要50秒钟以上,然后我必须关闭应用程序。“作为独立应用程序的应用程序监视器将再次打开它”,所以这不是问题。我实现了看门狗,它可以告诉我时间是否结束,然后关闭我的应用程序。我的问题是我是否做得正确。我测试了此解决方案一段时间后,看起来工作正常。
Main program 主程序
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);
}
}
}
}
Below appScheduler class : 在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);
}
}
}
}
I do a great deal of workflow type tasks every day. 我每天都会做大量的工作流类型任务。 I have tried to kick off jobs in the past the way you have here. 过去,我曾尝试过像您在这里一样开展工作。 The only time I use Thread.Sleep is to simulate some long running process in a test environment. 我唯一使用Thread.Sleep的目的是在测试环境中模拟一些长时间运行的过程。 I would look into using SetTimer. 我会考虑使用SetTimer。 Also using Thread.Sleep in a loop is not going to give you accurate results. 同样在循环中使用Thread.Sleep并不会给您准确的结果。 Now, that being said, keeping this running is going to be tricky. 话虽如此,保持这种运行状态将非常棘手。
Ultimately kicking off jobs on a regular basis is a breeze if you have an SQL server and can set the call up in an SSIS package. 如果您有一台SQL Server,并且可以在SSIS程序包中进行调用,那么最终定期地开始工作很容易。 Especially if you are are trying to do this in a web application which might just stop running after a period of time. 特别是如果您尝试在可能会在一段时间后停止运行的Web应用程序中执行此操作。 Good Luck 祝好运
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.