2011-12-06 7 views
3

この問題で最善の方法を進める方法がわかりません。Windowsサービス内のスレッド内のタイマー

今私は唯一のタスクは、特定のDSNでデータベースからデータを収集し、そのデータが有効であれば、メールを送信することで、Windowsのサービスを提供しています。このサービスには、5分ごとにチェックを入れ、上記のタスクを実行するタイマーが含まれています。

は今、私は以上の1つのDSN上で実行できるようにするには、Windowsのサービスを再作成する必要があります。 私はWindowsサービスの中でいくつかのスレッドを作って、それぞれのスレッドの中にseperatタイマーを持っていると考えていました。 これは良い考えですか?これはどのようにしてできますか?私は、各DSNにWindowsサービスを持たないようにしたい。私はいかなる意味

を作るいけない場合

病気、それを描くしよう

       Windows Service 

スレッド1(DSN1)------------------------ -----スレッド2(DSN2)----------------------スレッド3(DSN3)
タイマー(X minutsごとにティック)------ -----------タイマー(同じ)-------------------------タイマー(同じ)
ロジック() - - - - - - - - - - - - - - - - - - - - - - - 論理 - - - ---------------------------- Logic()

私の問題が理にかなっていることを祈っています。

答えて

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

フィードバックのおかげで、タイマー自体がスレッドを表していることに気づいていませんでした。だから私は完全にスレッドの部分を残すことができますか?バックグラウンドワーカーもスレッドを使用しているので、なぜそれを使用しますか?私が遭遇したもう一つの質問は、私のサービスを止めるときにスレッドを閉じる方法でしたが、スレッドは必要ありませんがタイマーしか必要ない場合、これはもう問題ありませんか? – 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に分かれています。これは、とMultipleSourceEmailServiceを実装して、コードが完成し、サービスのコンシューマがわからなくても複数のソースを入れ替えることができるということも意味します。

もちろん、上で実装されたEmailServiceは、複数のソースから順番にSendEmailsを行います - もしあなたがそれを並列に実行する必要があれば、あなたはあなたが持っているDSNごとに新しいThreadを開始するようEmailServiceを変更できます。それをMultiThreadedMultipleSourceEmailServiceと呼びますが、IEmailServiceのコンシューマーとして、あなたのスケジューリングはその違いを知らないでしょう。

関連する問題