2010-07-15 7 views
0

나는이 작품이 궁금합니다. 간단한 C# cmd 라인 응용 프로그램이 있습니다. 그것은 설정 시간 (윈도우 스케줄러를 통해)에서 이메일을 보냅니다.잠자기 후 메서드를 호출하는 스레드가 있어야합니까?

smtp가 실패라고 말하는 것이 좋은 생각일까요?

smtpException에서 나는 15 분 동안 잠들었던 스레드를 넣었다. 깨어 나면 다시 그 메서드를 호출합니다. 이번에는 smtp가 백업 될 예정입니다. 그렇지 않다면 smpt가 다시 온라인 상태가 될 때까지이 작업을 계속합니다.

내가 여기에 대해 놓친 부분이 있습니까? 나는 물론 이런 일이 벌어지고있는 로깅을 할 것이다.

답변

0

Windows 서비스 사용을 적극 권장합니다. 백그라운드에서 실행되는 장기 실행 프로세스는 오랜 시간 동안 기다려야하며 제어되고 기록되며 '모니터링 가능한'수명이 필요합니다. Windows 서비스의 기능입니다.

Thread.Sleep이 작업을 수행 할 수 있지만 다른 스레드 또는 다른 작업에서 인터럽트 가능하게하려면 Monitor.Wait (MSDN ref)을 권장합니다. 그런 다음 서비스에 의해 생성되고 관리되는 스레드에서 프로세스를 실행할 수 있습니다. 중지/인터럽트가 필요하면 동일한 동기화 개체에 Monitor.Pulse이 생기고 스레드는 다시 정상적으로 돌아옵니다.

또한 심판 :

Best architecture for a 30 + hour query

희망하는 데 도움이!

1

사실 이것은 효과적으로 구현하는 것이 Circuit-Breaker pattern의 간단한 변형입니다.

패턴의 배경은 외부 리소스가 다운 된 경우 몇 밀리 초 후에 다시 오지 않을 것이라는 사실입니다. 복구하는 데 약간의 시간이 필요할 수 있습니다. 일반적으로 회로 차단기 패턴은 평균 속도가 빠르기 때문에 사용자가 오류를 더 빨리받을 수 있습니다. 또는 실패한 시스템에서 더 많은 자원을 소비하지 않기 위해서입니다. 대기열에 넣을 수있는 물건이 있고 즉시 배달 할 필요가없는 경우처럼 자원을 다시 사용할 수있게 될 때까지 기다리는 것이 합리적입니다.

몇 가지주의 사항 : 완전히 실패하기 전에 최대 재 시도 횟수를 원할 수 있으며, 15 분 미만의 지연으로 시작하고 싶을 수 있습니다.

+0

회로 차단기 패턴은 외부 서비스의 과부하를 중지하는 데 사용됩니다. 그가 여기에있는 것은 "어떻게 든 작동하지 않는다면 나중에 어떤 외부의 힘이 뭔가 패턴을 고쳤을 수도 있기 때문에 나중에 다시 시도하십시오"라는 것입니다 - 1 –

+0

@Romain, 그리고 "외부의 힘"이 실제로 문제를 해결했을 수도 있습니다. 힘이 네트워크 기술자이거나 SMTP가 실제로 과부하로 인해 작동 중지되었습니다. 무한 루프가 아니어야한다는 데 동의하지만 오히려 나중에 트랜잭션을 다시 시도합니다. – driis

+0

-1을 제거하겠습니다. 나는 모든 곳의 패턴을 생각해 내고 모든 코드 라인에 표시하려고하는 것을 싫어합니다. 카운터를 재설정하는 데 필요한 답변을 수정하십시오. –

0

무한 루프는 항상 걱정입니다. N 번의 시도 후에 실패 할 수 있도록 설정해야하며 사용자 콘솔에서 시스템을 종료 할 수있는 방법이 있어야합니다.

실패가 당신 것이 아닌 경우 실패는 그렇게 나쁜 것이 아닙니다. 실패하게하고 실패한 이유를보고하십시오.

+0

예. 나는 카운터를 생각하고있었습니다. 어떻게 구현하나요? 콘솔에서 어떻게 종료할까요? 콘솔을 종료한다고 생각합니다. – chobo2

+0

카운 터가 초과되면 카운터가 정상적으로 작동하므로 잠자기/통화 쌍을 루프 및 보석금에 넣을 수 있습니다. 처음 5 분 동안 "고정"되지 않으면 다음 5 분 안에 해결되지 않을 수도 있기 때문에 매번 대기 시간을 연장 할 수도 있습니다 (지수 적 백 오프). 이는 예를 들어 이더넷 네트워크 충돌 감지 및 재전송에서 일반적입니다. 오래 기다리는 스레드를 종료하려면 루프에 코드를 추가하여 콘솔 입력을 확인하거나 "잊어 버려 집에 가라."라는 글로벌 부울 플래그를 확인하십시오. 사용자 입력에 응답하여 주 스레드에서 플래그를 설정하십시오. – dthorpe

+0

메소드를 다시 호출하는 것처럼 sleep/call 쌍을 얻지 못하면 더 이상 4 루프에 있지 않습니까? – chobo2

0

선택 사항은 제한되어 있습니다. 그것이 일시적인 조건이며 그것이 어느 시점에서 작동했다고 가정합니다. 당신이 할 수있는 유일한 일은 문제를 통보하고, 누군가 그것을 고치고 나중에 작업을 다시 시도하는 것입니다. 당신이해야 할 유일한 일은 당신이 잃지 않도록 메시지를 보호하는 것입니다.

0

동시성에주의를 기울이면, 한 번에 하나의 프로세스 만 실행되도록하는 명명 된 뮤텍스가있을 수 있습니다.

비슷한 방식으로 모든 개발자에게 알림을 보냅니다. 단, 메시지 본문과 주제를 데이터베이스에 저장합니다. 메시지가 성공적으로 처리 된 후 데이터베이스에 성공 플래그를 설정합니다. 이렇게하면 오류 및 재 시도를 쉽게 추적하고보고 할 수 있습니다.

1

지수 백 오프는 제가 생각하기에 일반적인 선택입니다. TCP가 연결을 시도하기 위해 사용하는 전략과 마찬가지로 실패한 각 시도에서 시간 초과를 두 배로 늘리십시오. 누군가가 잘못된 것을 알아 내기 전에 반복되는 실패 알림으로 프로그램이 이벤트 로그를 범람하지 않도록합니다. 어느 정도 걸릴 수 있습니다.

그러나 작업 스케줄러를 사용하면 확실히 도움이되지 않습니다. 프로그램을 다시 프로그래밍하여 프로그램이 불필요하게 컴퓨터 리소스를 소모하지 않도록해야합니다. 그러나 .NET에서 ITaskService 인터페이스를 사용하는 것은 쉽지 않습니다. this project을 확인하십시오.

관련 문제