我写的应用程序每分钟都在重复执行某项任务。问题是有时候(内部计算(因为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);
}
}
}
}
答案 0 :(得分:-1)
我每天都会做大量的工作流程类型的任务。我曾经试图像过去那样开始工作。我使用Thread.Sleep的唯一一次是在测试环境中模拟一些长时间运行的进程。我会研究使用SetTimer。在循环中使用Thread.Sleep也不会给你准确的结果。现在,正如所说,保持这种运行将是棘手的。
如果您拥有SQL服务器并且可以在SSIS包中设置调用,那么最终定期开始工作是轻而易举的。特别是如果您正在尝试在Web应用程序中执行此操作,该应用程序可能会在一段时间后停止运行。祝你好运