2011-12-06 4 views
3

이 문제를 해결하는 최선의 방법을 찾아 낼 수 없습니다.Windows 서비스 내의 스레드 내의 타이머

지금은 특정 DSN이있는 데이터베이스에서 데이터를 수집 한 다음 데이터가 유효한 경우 전자 메일을 보내는 작업 만하는 Windows 서비스가 있습니다. 이 서비스에는 매 5 분마다 틱하고 위의 작업을 수행하는 타이머가 있습니다.

이제 1 개 이상의 DSN에서 실행할 수 있도록 Windows 서비스를 다시 작성해야합니다. Windows 서비스 내부에서 여러 스레드를 만든 다음 각 스레드 안에 seperat 타이머를 다시 설치하려고합니다. 좋은 생각인가요? 어떻게 할 수 있습니까? 각 DSN에 대해 Windows 서비스가 없도록하고 싶습니다. 나는 어떤 의미

을 해달라고하면

일리노이을 그리는 시도

       Windows Service 

Thread1 (DSN1) ------------------------ ----- 스레드 2 (DSN2) ---------------------- 스레드 3 (DSN3)
타이머 (X 분마다 틱) ------ ----------- 타이머 (동일) ------------------------- 타이머 (동일)
로직() - --------------------------------------------논리----- ---------------------------- 논리()

호프 내 문제가 되길 바랍니다.

답변

5

각 타이머는 자체 스레드를 나타냅니다. 이것을 알기 때문에, 주어진 dsn마다 타이머 오브젝트를 동적으로 생성하려고합니다.

public partial class Service1 : ServiceBase 
{ 
    public Service1() 
    { 
     InitializeComponent(); 
    } 

    private List<GetDataFromDSN> list = null; 
    protected override void OnStart(string[] args) 
    { 
     list = new List<GetDataFromDSN>(); 
     // assume args contains your given dsn values 
     foreach (string dsn in args) 
     { 
      GetDataFromDSN newObj = new GetDataFromDSN(); 
      newObj.DSN = dsn; 
      list.Add(newObj); 
      newObj.Start(); 
     } 
    } 
} 

public class GetDataFromDSN 
{ 
    public string DSN { get; set; } 
    private Timer timer = null; 
    private double interval = 1000*60*5; // 5 minutes interval 
    public GetDataFromDSN() 
    { 
     // init your object 
     timer = new Timer(interval); 
     timer.Elapsed +=new ElapsedEventHandler(timer_Elapsed); 
    } 
    private void timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     // do what ever you want 
    } 
    public void Start() // or even make timer public 
    { 
     timer.Start(); 
    } 
    public void Stop() 
    { 
     timer.Stop(); 
    } 
} 
+0

@jrb에 따르면 타이머 대신 BackGroundWorker를 사용할 수도 있습니다. –

+0

+1. 이 맥락에서 심지어 실재 스레드가 없다는 것은 제로 센스를 만듭니다. 도대체 뭐야? 기다리고 있니? 타이머는 필요에 따라 스레드를 가져옵니다. – TomTom

+0

의견을 보내 주셔서 감사 드리며, 타이머 자체가 스레드임을 나타냅니다. 그래서 나는 나사 부분을 완전히 버릴 수 있었습니까? backgroundworker 스레드를 사용하여, 그럼 내가 왜 사용합니까? 내가 건너 왔던 또 다른 질문은 내 서비스를 중단 할 때 스레드를 닫는 방법 이었지만 스레드가 필요하지는 않지만 타이머 만 필요하면 더 이상 중요하지 않습니까? – Thomas

0

여기 System.Threading.Timer

, 희망이

public void StartDSNTimers() 
    { 
     _tmr1 = new Timer(CheckMessages, dsn1, 0, 60000); 
     _tmr2 = new Timer(CheckMessages, dsn2, 0, 60000); 
     _tmr3 = new Timer(CheckMessages, dsn3, 0, 60000); 
    } 

    private void CheckMessages(object obj) 
    { 
     //Logic 
    } 
4

이 DSN을 각각 별도의 스레드에있을 필요가 있는가 내 프로젝트의 샘플 코드를하는 데 도움이됩니다 사용해보십시오?

스레드가 호출 한 일종의 서비스 내에 전자 메일 검색 및 유효성 검사 논리를 캡슐화하려는 경우 다중 DSN이 있다는 사실을 예약 스레드에서 숨길 수 있습니다. 당신의 타이머 로직이 같은 단일 스레드에 남아있을 수 있습니다, 이러한 방법으로

public class MultipleSourcesEmailService : IEmailService 
{ 
    private IEnumerable<IDatabaseSource> databases; 
    public EmailService(params IDatabaseSource[] sources) 
    { 
     databases = new List<IDatabaseSource>(sources);   
    } 

    public void SendEmailsToValidAddresses() 
    { 
     foreach(var database in databases) 
     { 
      var emailAddresses = database.SelectAllEmailAddresses(); 
      ValidateAndSendEmailsTo(emailAddresses); 
     } 
    } 

    public void ValidateAndSendEmailsTo(IEnumerable<string> emailAddresses) 
    { 
     // Perform appropriate logic 
     ... 
    } 

}   

: 예를 들어, IEmailService는 다음과 같은 계약이있을 수 있습니다

public interface IEmailService 
{ 
    void SendEmailsToValidAddresses(); 
} 

및 구현은 다음과 같이 표시 될 수 있습니다 이메일을 보내는 데 대한 우려는 IEmailService으로 구분됩니다. 즉, SingleSourceEmailServiceMultipleSourceEmailService을 구현하고 코드가 완료되어 서비스 소비자가 모를 때 여러 소스를 바꿀 수 있다는 의미입니다.

물론 위에서 구현 한 EmailService는 여러 소스에서 순차적으로 SendEmails가됩니다. 병렬로 실행해야하는 경우 EmailService를 변경하여 사용자가 보유한 각 DSN에 대해 새 스레드를 시작할 수 있습니다. 그것을 MultiThreadedMultipleSourceEmailService이라고 부르지 만, IEmailService의 소비자로서 당신의 스케줄링은 결코 그 차이를 알 수 없을 것이다.

관련 문제