다중 타이머 경과 문제
-
21-12-2019 - |
문제
나는 아래에 정의 된 타이머가 있습니다.타이머는 장기 실행 작업을 실행합니다.문제가있는 문제는 타이머가 실행중인 경우 간격이 다시 경과했고 다른 타이머 실행은 I.E _timer_Elapsed
를 시작합니다.타이머가 완료된 후 타이머를 어떻게 실행할 수있는 시간을 어떻게 실행할 수 있습니까?이제는 한 번에 여러 타이머 실행이 발생할 수 있으며 코드와 모든 종류의 문제가 발생할 수 있습니다.
protected override void OnStart(string[] args)
{
_timer = new System.Timers.Timer();
_timer.AutoReset = false;
_timer.Interval = (Convert.ToInt32(ConfigurationManager.AppSettings["CheckInterval"]));
_timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true;
_timer.Start(); // Start timer
}
public static void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
_timer.Interval = (Convert.ToInt32(ConfigurationManager.AppSettings["CheckInterval"]));
BLLGenericResult SystemCheckItems_Result = ServiceItemOperations.CheckItems(); // Long Running Task
}
catch (Exception ex)
{
// Exception handling...
}
finally
{
_timer.Start();
}
}
. 해결책
제대로이 작업을 써 보겠습니다. 그것은 당신을 곤경에 빠뜨리는 간격 과제입니다. 문제를 보여주는 샘플 프로그램 :
using System;
class Program {
static System.Timers.Timer timer;
static void Main(string[] args) {
timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
timer.Start();
Console.ReadLine();
}
static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
timer.Interval = 1000;
Console.WriteLine("Tick");
}
}
.
출력 :
Tick
Tick
Tick
...
.
경과 이벤트 핸들러에서 간격 할당을 제거하여 차이를 확인하십시오.
그래서, 즉, 오토 축소 속성이 false 이지만, 간격 속성을 할당하기 만하면 타이머를 다시 시작할만큼 충분합니다. 물론 큰 놀라움, 아무도 그 일을 보지 못했습니다. 그리고 그것은 당신이 일찍 간격 속성을 할당하기 때문에, 이전에 무거운 리프팅을 시작하기 시작하기 때문에 프로그램에 HAVOC를 재생합니다. 따라서 경과 된 이벤트는 다른 스레드에서 다시 발생하며 이전에는 아직 실행을 완료하지 않았습니다. 그것은 특히 간격 값이 너무 작 으면 일어날 때 일어나기를 기다리는 스레딩 버그입니다. 나중에 할당해야 할 필요가있어 마지막으로 블록 내에서 그렇게하십시오. 간격을 너무 작게 만들었습니다. 나중에 진단하기가 매우 어렵습니다.
이 C # 버그입니까?
C # 언어가 훅 꺼져 있습니다. 이것은 .NET Framework 버그입니다. system.timers.timer는 일반적으로 매우 좋은 수업이 아니며 안전 스위치가없는 전기 톱의 유용성을 가지고 있습니다. 그것은 System.Threading.timer 클래스를 더 사용할 수있게하는 것을 의미했습니다. 특히 곧 쓰레기가되는 습관으로 문제를 해결할 수 있습니다. 한 가지 문제가 해결되었지만 세 가지 새로운 문제가 추가되었습니다. 이것은 훈련 바퀴가있는 프레임 워크 버전 인 .NET 1.0으로 돌아갑니다. 그들은 단지 더 이상 고칠 수 없으며 기존 코드가 너무 많아집니다. System.Threading.timer로 정말로 더 꺼집니다 .Timer는 변수에서 언급 된 객체를 유지해야합니다. 당신이 이미하는 것처럼.
다른 팁
2017 업데이트 :
이러한 종류의 문제에 유용 할 수있는 새로운 도구가 있습니다.
await Task.Delay(TimeSpan.FromSeconds(x));
.