2013-05-15 2 views
3

나는 기본적으로 다음 코드를 실행하는 Windows 서비스 일하고 :예외가 잡힐 때 타이머 콜백이 중지되는 이유는 무엇입니까?

public class ServiceController 
{ 
    private FundsEngine _fundsEngine; 

    protected override void OnStart(string[] args) 
    { 
    var logsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs"); 
    if (Directory.Exists(logsPath) == false) 
    { 
     Directory.CreateDirectory(logsPath); 
    } 

    _fundsEngine = new FundsEngine(); 
    _fundsEngine.Start(); 
    } 
} 

서비스는 지정된 간격에 코드를 실행하도록 타이머를 사용하는 클래스입니다 "엔진"을 시작할 수 있습니다.

다음 클래스는 System.Threading.Timer을 사용하여 콜백 (OnTick())을 5 초마다 호출하는 엔진의 예입니다. 아래에 도시 된 바와 같이 로그

public class FundsEngine 
{ 
    private System.Threading.Timer _timer; 
    private static Logger _logger = LogManager.GetCurrentClassLogger(); 

    public void Start() 
    { 
    _logger.Trace("Begin Start"); 

    try 
    { 
     // details omitted 

     _timer = new Timer(OnTick); 
     _timer.Change(5000, Timeout.Infinite); 
    } 
    catch (Exception exception) 
    { 
     _logger.ErrorException("Error in Start.", exception); 
    } 
    finally 
    { 
     _logger.Trace("End Start"); 
    } 
    } 

    private void OnTick(object state) 
    { 
    _logger.Trace("Begin Tick"); 

    try 
    { 
     // do stuff 
     _timer.Change(5000, Timeout.Infinite); 
    } 
    catch (Exception exception) 
    { 
     _logger.ErrorException("Error in Tick. ", exception); 
    } 
    finally 
    { 
     _logger.Trace("End Tick"); 
    } 
    } 
} 

, 상기 타이머는 OnTick() 방법 5 초마다 호출 예상 작동으로. 예외가 OnTick() 메소드 내에서 캐치되는 경우에

2013-05-14 16:27:01.2261|TRACE|Begin Start 
2013-05-14 16:27:03.8514|TRACE|End Start 
2013-05-14 16:27:08.8569|TRACE|Begin Tick 
2013-05-14 16:27:08.8709|TRACE|End Tick 
2013-05-14 16:27:13.8734|TRACE|Begin Tick 
2013-05-14 16:27:13.8734|TRACE|End Tick 
2013-05-14 16:27:18.8809|TRACE|Begin Tick 
2013-05-14 16:27:18.8809|TRACE|End Tick 
2013-05-14 16:27:23.8894|TRACE|Begin Tick 
2013-05-14 16:27:23.8894|TRACE|End Tick 
2013-05-14 16:27:28.8969|TRACE|Begin Tick 
2013-05-14 16:27:28.8969|TRACE|End Tick 
2013-05-14 16:27:33.9044|TRACE|Begin Tick 
2013-05-14 16:27:33.9044|TRACE|End Tick 

, 내 기대는 기록되고, 서비스가 OnTick() 방법 5 초에 다시 호출됩니다 있도록, 계속 실행하는 것입니다. 그러나 예외가 처리 된 후에 콜백이 다시 호출되지 않으므로이 경우가 아닙니다. 왜 이런거야?

2013-05-14 16:29:03.8574|TRACE|Begin Start 
2013-05-14 16:29:03.8574|TRACE|End Start 
2013-05-14 16:29:08.8709|TRACE|Begin Tick 
2013-05-14 16:29:09.9750|ERROR|Error in Tick. System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it 127.0.0.1:22 
2013-05-14 16:29:09.9750|TRACE|End Tick 

답변

1
_timer.Change(5000, Timeout.Infinite); 

당신은 기간 인수에 대해 무한 통과, 기간 타이머를 작성하지 않았다. 타이머는 OnTick()을 한 번만 호출합니다. 그러나 코드가 매우 불완전하기 때문에 타이머를 다시 충전하려면 Change()를 다시 호출해야합니다. 이 변경() 호출이 예외를 우회지고 있음을

그래서 높은 확률. 계속 유지하려면이 Change() 호출이 에 있고 마지막으로 블록에 속합니다. 이 작업을 수행하는 것이 실제로 좋은 생각은 아니지만 프로세스 상태가 손상된 0이 아닌 확률은 다시 충돌합니다. 계속해서. 적어도 이것에 대한 대책을 강구해야하며 반복적으로 폭탄을 투하 할 때 포기하는 연속적인 충돌의 횟수를 계산해야합니다.

+0

모든 점을 수정하십시오. 원본 본문을 편집하여 누락 된 세부 사항을 표시합니다. 내가 그것을 놓쳤던 방법을 명확히하지 않고있다. 그러나 그것은 명백하게 완전한 의미를 가진다. –

1

예외의 경우 ...

System.Threading.Timer에서 프로그램을 종료합니다 this StackOverflow 후 상태에 허용 대답. 내가 믿는

당신이보고있는 것입니다.

+0

나는 이것을보고 있지만 [여기] (http://stackoverflow.com/a/1718610/213159) 언급하지만, 설명을 찾을 수 없어으로는, 처리되지 않은 예외를 참조 생각했다. –

+0

그래서 try catch 블록 내에서 전체 호출 된 함수를 사용하는 것 외에 다른 방법으로 처리 할 수있는 방법은 없습니다. – MonsterMMORPG

관련 문제