2009-11-30 7 views
1

Je suis très nouveau dans la programmation multi-thread. Voici ce que je suis en train de réaliser:C# - File d'attente et multithread

  • Créer un service Windows qui lit en permanence la base de données (ou somekind de file d'attente de messages, s'il vous plaît suggérer ce qui serait le mieux) pour une entrée dans une table.
  • Rechercher une nouvelle entrée dans la table
  • S'il y a une nouvelle entrée, vérifier s'il y a suffisamment de fil dans le threadpool (ne sais pas comment cela pourrait fonctionner), commencer un nouveau thread et faire un peu travail. Il pourrait y avoir beaucoup de nouvelles entrées pendant le trafic élevé c'est pourquoi j'ai besoin de l'avoir multi-thread.

Merci à tous. S'il vous plaît aidez-moi avec des idées et un lien. J'apprécie ton aide.

+0

Si vous utilisez une file d'attente de messages plutôt qu'une table de base de données, considérez-vous qu'un message de file d'attente est une 'nouvelle entrée' ou est-ce une valeur spécifique que le message pourrait contenir? –

+0

Un message de file d'attente serait une nouvelle entrée. La nouvelle entrée sera également supprimée de la file d'attente si elle est traitée avec succès. – Emon

Répondre

2

Si possible, vous pouvez envisager d'avoir la base de données envoyer des signaux en cas de modification. Les lectures continues semblent être un design en arrière. Si vous ne souhaitez pas créer votre propre service, vous pouvez utiliser Windows Scheduling Services pour lancer votre application afin de lire la base de données. Vous ne seriez pas en mesure d'utiliser un ThreadPool pour limiter le nombre d'actions simultanées. Mais si vous créez votre propre service, l'utilisation de la classe ThreadPool est assez simple. Vous pouvez simplement définir une limite de fil et conserver queuing éléments de travail en fonction des mises à jour de base de données. Aussi jouer avec le SetMinThreads, pour garder les discussions actives et réutilisables.

0

Si vous utilisez SQL Server, vous pouvez utiliser SqlCacheDependency Class pour surveiller les modifications de la base de données.

1

Tout ce dont vous avez besoin est un ThreadPool et MSMQ (pardonnez le lien vers un article VB.NET); très trivial. Ce que vous avez écrit dans votre exemple est l'interrogation, pas une file d'attente, techniquement.

1

D'où cette table est-elle actualisée et pourquoi?

Si vous utilisez simplement cette table comme un moyen de «communiquer» entre deux applications, alors je suggère d'utiliser un système EMS comme MSMQ. Vous pouvez faire en sorte que vos deux applications se parlent entre elles et bénéficient de tous les avantages de la livraison de guareteed fournis avec MSMQ. Il est également cuit dans la WCF et assez facile à intégrer.

Si cette table est mise à jour à d'autres fins (par exemple si vous n'essayez pas de créer votre propre système de mise en file d'attente), je suis d'accord avec Rashmi sur la recommandation SqlCacheDepdency. Cela vous permettra essentiellement d'accrocher votre code .NET en SQL afin qu'un événement soit levé lorsqu'un nouvel enregistrement dans la table est ajouté ou qu'un enregistrement existant est mis à jour (ou n'importe quoi change le jeu de résultats pour cette question).

0

Comme d'autres l'ont dit, vous seriez probablement mieux servi en utilisant MSMQ. Je vais aller plus loin et je vous encourage à écrire votre service en utilisant WCF et le déployer sur IIS. Ce n'est pas vraiment facile, mais Microsoft a déjà fait beaucoup de travail que vous aimeriez faire.

Tom Hollander a une grande série d'articles sur la mise en place MSMQ, WCF et IIS ici:

http://blogs.msdn.com/tomholl/archive/2008/07/12/msmq-wcf-and-iis-getting-them-to-play-nice-part-1.aspx

1

J'ai codé précisément ce genre de service Windows, et je pense que vous êtes sur la bonne voie.J'utilise une table de base de données pour ma file d'attente, ce qui me donne une file d'attente persistante en cas de plantage du système, permet à plusieurs rédacteurs de traverser le réseau local et me permet de gérer les conflits via les transactions.

Je crée des threads séparés pour chaque processus et je garde une trace du nombre de threads actifs, ce qui me permet d'ajuster à la volée. Étant donné que chaque thread effectue un appel de service Web, l'utilisation du pool de threads a présenté un avantage négligeable, ce qui m'a également permis de démarrer un grand nombre de threads car ils bloquaient l'attente sur un serveur externe.

Il est facile à gérer si vous n'autorisez qu'un seul lecteur, ce qui vous permet de suivre les entrées de file d'attente que vous avez lues en utilisant simplement une colonne d'identité et en sélectionnant la suivante plus haute que la dernière. Lorsqu'un thread termine, il peut supprimer l'entrée sur laquelle il travaillait. Si votre service tombe en panne, il récupérera simplement la première entrée non lue. Vous pouvez obtenir colombophile en incluant une colonne qui indique quand l'entrée a été touchée, et si le traitement échoue (peut-être en raison d'un délai d'attente réseau) alors vous pouvez le déconnecter et le laisser attraper par la lecture suivante. Si vous avez besoin de plusieurs lecteurs, utilisez un champ d'horodatage qui indique quand il a été touché; un lecteur peut récupérer pour un autre lecteur écrasé en vérifiant quand une entrée a été touchée. Vous devez également intercepter l'événement de fermeture de service afin que vous puissiez terminer le traitement proprement, et inclure votre propre journalisation afin que vous puissiez suivre ce qui se passe une fois que vous avez plusieurs écrivains simultanés. Considérez également une version de test qui vous permet de marteler votre lecteur de file d'attente et de mesurer comment il supporte sous charge. Cela ira un long chemin pour vous aider à éliminer les pièges pas si évidents qui se cachent dans une application multi-thread.

Mais j'ai eu une explosion en créant ceci et j'espère que vous aussi.