문제

나는 아래에 정의 된 타이머가 있습니다.타이머는 장기 실행 작업을 실행합니다.문제가있는 문제는 타이머가 실행중인 경우 간격이 다시 경과했고 다른 타이머 실행은 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)); 
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top