2011-06-06 6 views
1

Je travaille sur un service Windows dans lequel j'aimerais avoir deux threads. Un thread doit rechercher des mises à jour (dans un flux RSS) et insérer des lignes dans une base de données lorsque des mises à jour sont trouvées.Windows Service et multithread

Lorsque les mises à jour se trouvent que je voudrais envoyer une notification via un autre thread, qui accède à la base de données, reçoit les messages et les destinataires et envoie ensuite les notifications.

La meilleure solution est peut-être de ne pas utiliser deux threads. Dois-je avoir des connexions DB dans les deux threads?

Quelqu'un pourrait-il me donner des conseils pour résoudre ce problème?

Répondre

2

La principale raison de faire une multithread d'application ou d'un service est d'effectuer la base de données ou d'autres opérations sans arrière-plan de blocage (à savoir la pendaison) un élément de présentation comme un formulaire Windows. Si votre service dépend d'un interrogation très rapide ou si vous pensez que les insertions db prennent beaucoup de temps, il peut être judicieux d'utiliser deux threads. Mais je ne peux pas imaginer que ce soit le cas dans votre scénario.

Si vous décidez de rendre votre service multithread, les deux principales classes de C# que vous voulez examiner sont BackgroundWorker et ThreadPool. Si vous souhaitez effectuer plusieurs insertions db simultanées (par exemple, si vous souhaitez exécuter une insertion pour chacun des flux RSS multiples interrogés en même temps), vous devez utiliser un ThreadPool. Sinon, utilisez un BackgroundWorker.

En règle générale, vous auriez une classe d'accès db qui aurait une méthode pour insérer une ligne. Cette méthode crée un worker d'arrière-plan, ajoute un gestionnaire DoWork à une méthode statique dans cette classe d'accès db au worker d'arrière-plan, puis appelle DoWorkAsync. Vous ne devriez avoir que des paramètres de connexion db dans cette classe afin de faciliter la maintenance du code. Par exemple:

public static class DbAccess 
{ 
    public void InsertRow(SomeObject entity) 
    { 
     BackgroundWorker bg = new BackgroundWorker(); 
     bg.DoWork += InsertRow_DoWork; 
     bg.RunWorkerCompleted += InsertRow_RunWorkerCompleted; 
     bg.RunWorkerAsync(entity); 
    } 

    private void InsertRow_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker bg = sender as BackgroundWorker; 
     SomeObject entity = e.Argument as SomeObject; 

     // insert db access here 
    } 

    private void InsertRow_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // send notifications 
     // alternatively, pass the InsertRow method a 
     // delegate to a method in the calling class that will notify 
    } 
}