如何确定我的 Windows 计时器是否 运行 完美并且不会导致任何内存泄漏
How to find out if my Windows timer is running perfect and not causing any memory leak
我在一个 WinForm 中为不同的进程调用两个计时器,它们都使用相同的 try-catch 格式。前几天它工作正常,然后开始变慢。我可以看到服务器上有一些负载。我的计时器事件是否正确?这个活动负荷不大吗?
在我的 try-catch 中,我只在我的代码捕获到任何异常时才停止计时器。我怀疑如果没有例外,我的时间没有停止。如果我第二次启动计时器,它会增加负载或只是重置。请提出您的宝贵意见。提前致谢。
我的代码如下。
计时器 1 刻度:
private void timerMain_Tick(object sender, EventArgs e)
{
try
{
// Retrieve some status and Update
}
catch (Exception ex)
{
timerMain.Stop();
MessageBoxHelper.ShowException(LanguagePack.LanguageHelper.GetString(GlobalParameters.Language, "Error_ExecutionEx"), ex);
}
finally
{
timerMain.Start();
}
}
计时器 2 刻度:
private void timerWorkStep_Tick(object sender, EventArgs e)
{
try
{
// Retreive Some value from web proxy and set to label
}
catch (Exception ex)
{
timerWorkStep.Stop();
MessageBoxHelper.ShowException(LanguagePack.LanguageHelper.GetString(GlobalParameters.Language, "Error_ExecutionEx"), ex);
}
finally
{
timerWorkStep.Start();
}
}
我错过了这个问题,但 OP 在评论中向我指出了这个问题,所以这是我的答案。
我不会说你确实有内存泄漏,因为你最终释放了你正在使用的内存和资源,但正如你在评论中指出的那样,我绝对同意只在捕获时停止你的计时器并且始终在 finally 中启动它肯定会导致您的滴答声 运行 比固定间隔更频繁。如果你运行下面的例子你就会明白我的意思。
计时器运行一次多次滴答示例
void Main()
{
_timer = new System.Timers.Timer(100);
_timer.Elapsed += Timer_Elapsed;
_timer.Start();
}
private void Timer_Elapsed(object sender, EventArgs e)
{
try
{
for (int i = 0; i < 15; i++)
{
Console.Write(i + " ");
Thread.Sleep(10);
}
Console.WriteLine();
}
catch (Exception ex)
{
_timer.Stop();
Console.WriteLine(ex.Message);
}
finally
{
_timer.Start();
}
}
private System.Timers.Timer _timer;
我的大部分 windows 服务定期使用计时器,我们采用的模式是停止计时器作为滴答中的第一件事,并在滴答结束后重新启动它。它下面的代码的问题是它不会 运行 每个定义的间隔,因为实际处理需要时间
定时器模式
private void Timer_Elapsed(object sender, EventArgs e)
{
try
{
_timer.Stop();
//some work
}
catch(Exception ex)
{
}
finally
{
_timer.Start();
}
}
如果您希望在每小时 5 点获得更多可靠的 运行,您将需要执行以下操作:
可靠间隔的定时器模式
public class NextRunCalculator
{
public double CalculateTimeUntilNextRun()
{
List<int> processingMinutes = new List<int> { ServiceConstants.RunMinute5 };//this is a list of minutes during the hour you want the service to run
int t = int.MaxValue;
foreach (var processingMinute in processingMinutes)
{
var minutesRemaining = processingMinute - DateTime.Now.Minute;
if (minutesRemaining <= 0)
{
minutesRemaining = 60 + minutesRemaining;//change 60 to however often you want the timer to run
}
if (minutesRemaining < t)
{
t = minutesRemaining;
}
}
return TimeSpan.FromMinutes(t).TotalMilliseconds;
}
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
_timer.Stop();
//do work
_timer.Interval = _nextRunCalculator.CalculateTimeUntilNextRun();
_timer.Start();
}
我在一个 WinForm 中为不同的进程调用两个计时器,它们都使用相同的 try-catch 格式。前几天它工作正常,然后开始变慢。我可以看到服务器上有一些负载。我的计时器事件是否正确?这个活动负荷不大吗?
在我的 try-catch 中,我只在我的代码捕获到任何异常时才停止计时器。我怀疑如果没有例外,我的时间没有停止。如果我第二次启动计时器,它会增加负载或只是重置。请提出您的宝贵意见。提前致谢。
我的代码如下。
计时器 1 刻度:
private void timerMain_Tick(object sender, EventArgs e)
{
try
{
// Retrieve some status and Update
}
catch (Exception ex)
{
timerMain.Stop();
MessageBoxHelper.ShowException(LanguagePack.LanguageHelper.GetString(GlobalParameters.Language, "Error_ExecutionEx"), ex);
}
finally
{
timerMain.Start();
}
}
计时器 2 刻度:
private void timerWorkStep_Tick(object sender, EventArgs e)
{
try
{
// Retreive Some value from web proxy and set to label
}
catch (Exception ex)
{
timerWorkStep.Stop();
MessageBoxHelper.ShowException(LanguagePack.LanguageHelper.GetString(GlobalParameters.Language, "Error_ExecutionEx"), ex);
}
finally
{
timerWorkStep.Start();
}
}
我错过了这个问题,但 OP 在评论中向我指出了这个问题,所以这是我的答案。
我不会说你确实有内存泄漏,因为你最终释放了你正在使用的内存和资源,但正如你在评论中指出的那样,我绝对同意只在捕获时停止你的计时器并且始终在 finally 中启动它肯定会导致您的滴答声 运行 比固定间隔更频繁。如果你运行下面的例子你就会明白我的意思。
计时器运行一次多次滴答示例
void Main()
{
_timer = new System.Timers.Timer(100);
_timer.Elapsed += Timer_Elapsed;
_timer.Start();
}
private void Timer_Elapsed(object sender, EventArgs e)
{
try
{
for (int i = 0; i < 15; i++)
{
Console.Write(i + " ");
Thread.Sleep(10);
}
Console.WriteLine();
}
catch (Exception ex)
{
_timer.Stop();
Console.WriteLine(ex.Message);
}
finally
{
_timer.Start();
}
}
private System.Timers.Timer _timer;
我的大部分 windows 服务定期使用计时器,我们采用的模式是停止计时器作为滴答中的第一件事,并在滴答结束后重新启动它。它下面的代码的问题是它不会 运行 每个定义的间隔,因为实际处理需要时间
定时器模式
private void Timer_Elapsed(object sender, EventArgs e)
{
try
{
_timer.Stop();
//some work
}
catch(Exception ex)
{
}
finally
{
_timer.Start();
}
}
如果您希望在每小时 5 点获得更多可靠的 运行,您将需要执行以下操作:
可靠间隔的定时器模式
public class NextRunCalculator
{
public double CalculateTimeUntilNextRun()
{
List<int> processingMinutes = new List<int> { ServiceConstants.RunMinute5 };//this is a list of minutes during the hour you want the service to run
int t = int.MaxValue;
foreach (var processingMinute in processingMinutes)
{
var minutesRemaining = processingMinute - DateTime.Now.Minute;
if (minutesRemaining <= 0)
{
minutesRemaining = 60 + minutesRemaining;//change 60 to however often you want the timer to run
}
if (minutesRemaining < t)
{
t = minutesRemaining;
}
}
return TimeSpan.FromMinutes(t).TotalMilliseconds;
}
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
_timer.Stop();
//do work
_timer.Interval = _nextRunCalculator.CalculateTimeUntilNextRun();
_timer.Start();
}