2010-07-26 4 views

Répondre

4

Je recommande d'utiliser la classe Task (ajoutée dans .NET 4.0) si vous avez besoin de ce type de comportement. Il prend en charge l'annulation, et vous pouvez avoir n'importe quel nombre de tâches en écoutant le même jeton d'annulation, ce qui vous permet de les annuler tous avec un seul appel de méthode.

Mise à jour (solution non 4.0):

Vous avez vraiment que deux choix. Un: implémentez votre propre démultiplexeur d'événements (c'est beaucoup plus complexe qu'il n'y paraît, en raison de la limite d'attente de 64-handle); Je ne peux pas recommander ceci - je devais le faire une fois (dans le code non managé), et c'était hideux.

Cela laisse le deuxième choix: Avoir un signal pour annuler les tâches. Naturellement, RegisteredWaitHandle.Unregister peut annuler la partie RWFSO. Le QUWI est plus complexe, mais peut être fait en rendant l'action consciente d'une valeur de "jeton". Lorsque l'action s'exécute, elle vérifie d'abord la valeur du jeton par rapport à sa valeur de jeton stockée; si elles sont différentes, alors il ne devrait rien faire.

Une chose importante à considérer est les conditions de course.N'oubliez pas qu'il existe une condition de concurrence entre l'annulation d'une action et le ThreadPool qui l'exécute, de sorte qu'il est possible de voir les actions en cours après l'annulation.

Je a blog post on this concept, que j'appelle « contextes de rappel asynchrone ». Le type CallbackContext mentionné dans le billet de blog est disponible dans la bibliothèque Nito.Async.

+0

Excellent conseil. –

+0

+1, mais Management ne veut pas que .NET 4.0 soit implémenté dans notre infrastructure pour le moment. – jp2code

+1

@ jp2code: C'est dommage; .NET 4.0 apporte d'énormes changements utiles au multithreading dans .NET. Voir ma réponse mise à jour pour une solution pré-NET 4.0. –

3

Il n'y a pas d'interface pour supprimer un élément en file d'attente. Cependant, rien ne vous empêche d'empoisonner le délégué pour qu'il revienne immédiatement.

modifier

Sur la base de ce que Paul a dit, je pense que vous pourriez aussi envisager une architecture pipe-line, où vous avez un nombre fixe de threads de lecture à partir d'une file d'attente de blocage (comme .NET 4.0' s BlockingCollection sur un ConcurrentQueue). De cette façon, si vous voulez annuler des articles, vous pouvez simplement accéder à la file d'attente vous-même. Cela dit, le conseil de Stephen à propos de Task est probablement meilleur, car il vous donne tout le contrôle que vous voulez de façon réaliste, sans tout le travail que nécessite votre propre pipeline. Je mentionne cela seulement pour l'achèvement.

+0

Steven: Voulez-vous dire ajouter quelque chose à la 'GetDataThread' qui l'amène à revenir? – jp2code

+0

Oui, exactement. Quelque chose que les nouveaux emplois vérifient au début et échouent immédiatement lors de la détection. Un 'bool volatil 'fera l'affaire. –

+0

Pour réitérer ce que Stephen a dit, l'annulation implique intrinsèquement une condition de concurrence, donc vous devriez vous attendre à ce qu'il arrête seulement les travaux avant qu'ils ne commencent. Sans doute, vous pouvez vérifier le drapeau d'annulation à d'autres intervalles pratiques, mais c'est un peu incertain. –

1

Le ThreadPool existe pour vous aider à gérer vos threads. Vous ne devriez pas avoir à vous soucier de la purger du tout, car elle prendra les meilleures décisions de performance en votre nom. Si vous pensez avoir besoin d'un contrôle plus strict de vos threads, vous pouvez envisager de créer votre propre classe de gestion des threads (similaire à ThreadPool), mais cela prendra beaucoup de travail pour égaler et dépasser les fonctionnalités intégrées dans ThreadPool.

Prenez a look here à certaines des optimisations ThreadPool et les idées qui la sous-tendent. Pour mon deuxième point, j'ai trouvé an article on Code Project qui implémente un "Threadpool annulable", probablement pour certaines de vos propres raisons. Ce serait un bon endroit pour commencer à regarder si vous allez écrire le vôtre.

+1

L'article Code Project utilise 'Abort', ce qui n'est pas une bonne idée. Cela dit, vous avez peut-être raison de ne pas avoir vraiment besoin de purger la piscine. –