我在创建计时器时遇到问题,启动时首先会睡2分钟。它总共运行5分钟,每分钟都可以运行。这就是我所拥有的:
class Program{
static System.Timers.Timer aTimer;
static System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
static TimeSpan LongToRun = new TimeSpan(0,300,0)); //run for 5 minutes
static void Main (string[] args){
Thread.Sleep(120000); //sleep for 2 mins
sw.Reset();
sw.Start();
Start();
}
static void Start()
{
aTimer = new System.Timers.Timer();
aTimer.Interval = 60000; //every min
aTimer.Enabled = true;
aTimer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
aTimer.Start();
}
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
TimeSpan ts = sw.Elapsed;
if (ts.TotalSeconds >= LongToRun.TotalSeconds)
{
aTimer.Stop();
return;
}
DoWork();
}
}
timer_Elapsed永远不会被调用......我是否会这样做?
提前致谢!!
答案 0 :(得分:1)
启动过程在启动计时器后立即返回并返回主程序。主程序结束,仍在运行的计时器在结束之前完成。
解决方案:确保您的程序运行时间足以让计时器过去。
另一个问题是您在启动计时器后订阅了该事件。这可能不是问题的原因,但在启动计时器之前,整齐的代码将是订阅。
顺便说一下,timer类实现了IDisposable。这意味着该类的设计者通知您他使用了需要尽快释放的稀缺资源。考虑在不再需要时立即处理Timer类。 using(...)语句是理想的。
使用async-await可以使您的代码更易于阅读和维护。
请考虑以下代码:
public static void Main()
{
Thread.Sleep(TimeSpan.FromMinutes(2));
var myTask = Task.Run( () => WorkerTask())
Task.Wait(myTask);
}
private static TimeSpan longToRun = new TimeSpan.FromMinutes(5);
// easier to read than new TimeSpan(0,300,0));
public static async Task WorkerTask()
{
StopTime = DateTime.Now + longToRun;
// repeatedly wait a while and DoWork():
while (DateTime.Now < StopTime)
{
await Task.Delay(TimeSpan.FromMinutes(2);
DoWork();
}
}
全部,不需要ManualResetEents,没有Stopwatches,没有Timers也没有timer_elapsed事件处理程序。
将参数传递给过程WorkerTask()甚至取消事件也很容易,因为操作员按下&lt; esc&gt;如果您创建CancellationTokenSource并将CancellationToken作为参数传递给WorkerTask,则很容易。事实上,这会使代码更简单:
public static void Main()
{
Thread.Sleep(TimeSpan.FromMinutes(2));
using (var tokenSource = new CancellationTokenSource())
{
var myTask = Task.Run( () => WorkerTask(tokenSource.Token))
tokenSource.CancelAfter(TimerSpan.FromMinutes(5));
// instead of LongToRun
Task.Wait(myTask);
}
}
public static async Task WorkerTask(CancellationToken token)
{
// repeatedly wait a while and DoWork():
while (!token.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromMinutes(2, token);
DoWork();
}
}
更多信息:
答案 1 :(得分:0)
首先,您设置了错误的时间段:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
从不调用timer_Elapsed,因为您的应用程序先前已关闭。最后添加Console.ReadLine()。
static TimeSpan LongToRun = new TimeSpan(0,**5**,0)); //run for 5 minutes
答案 2 :(得分:0)
正如谢尔盖所指出的那样,在Timespan LongToRun中设置的时间段内存在错误。我尝试过一个只有Thread.sleep函数的鳕鱼。希望代码对您有所帮助。
class Program {
static System.Timers.Timer aTimer;
static System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
static TimeSpan LongToRun = new TimeSpan(0,5,0); //run for 5 minutes
static void Main (string[] args) {
Console.WriteLine("Start Of Program" + DateTime.Now);
Thread.Sleep(120000); //sleep for 2 mins
sw.Reset();
sw.Start();
Start();
}
static void Start() {
TimeSpan ts = sw.Elapsed;
while (ts.TotalSeconds < LongToRun.TotalSeconds) {
doWork();
Thread.Sleep(60000);
ts = sw.Elapsed;
}
Console.WriteLine("End of program");
Console.ReadLine();
}
static void doWork() {
Console.WriteLine(DateTime.Now);
}
}