using System; using System.ServiceProcess; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; namespace Console_SendMail { public partial class MailService : ServiceBase { private CancellationTokenSource _cancellationTokenSource; private Task _serviceTask; public MailService() { InitializeComponent(); ServiceName = "EETGWMailService"; CanStop = true; CanPauseAndContinue = false; AutoLog = true; } protected override void OnStart(string[] args) { try { EventLog.WriteEntry(ServiceName, "메일 서비스가 시작됩니다.", EventLogEntryType.Information); _cancellationTokenSource = new CancellationTokenSource(); _serviceTask = Task.Run(() => DoWork(_cancellationTokenSource.Token)); EventLog.WriteEntry(ServiceName, "메일 서비스가 성공적으로 시작되었습니다.", EventLogEntryType.Information); } catch (Exception ex) { EventLog.WriteEntry(ServiceName, $"서비스 시작 중 오류 발생: {ex.Message}", EventLogEntryType.Error); throw; } } protected override void OnStop() { try { EventLog.WriteEntry(ServiceName, "메일 서비스를 중지합니다.", EventLogEntryType.Information); _cancellationTokenSource?.Cancel(); if (_serviceTask != null) { // 최대 30초 대기 if (!_serviceTask.Wait(TimeSpan.FromSeconds(30))) { EventLog.WriteEntry(ServiceName, "서비스 중지 시간 초과", EventLogEntryType.Warning); } } EventLog.WriteEntry(ServiceName, "메일 서비스가 중지되었습니다.", EventLogEntryType.Information); } catch (Exception ex) { EventLog.WriteEntry(ServiceName, $"서비스 중지 중 오류 발생: {ex.Message}", EventLogEntryType.Error); } finally { _cancellationTokenSource?.Dispose(); _serviceTask?.Dispose(); } } private void DoWork(CancellationToken cancellationToken) { // 기존 프로그램의 while 루프 로직을 여기로 이동 EventLog.WriteEntry(ServiceName, "메일 서비스 작업을 시작합니다.", EventLogEntryType.Information); while (!cancellationToken.IsCancellationRequested) { try { // 기존 메일 처리 로직 실행 Program.ExecuteMailOperations(); // 1초 대기 (cancellation token으로 중단 가능) if (cancellationToken.WaitHandle.WaitOne(1000)) { break; // 취소 요청 시 종료 } } catch (Exception ex) { EventLog.WriteEntry(ServiceName, $"메일 처리 중 오류 발생: {ex.Message}", EventLogEntryType.Error); // 오류 발생 시 5초 대기 후 재시도 if (cancellationToken.WaitHandle.WaitOne(5000)) { break; } } } EventLog.WriteEntry(ServiceName, "메일 서비스 작업이 종료되었습니다.", EventLogEntryType.Information); } private void InitializeComponent() { // // MailService // this.ServiceName = "EETGWMailService"; } } }