Appelez un délégué sur un thread spécifique C#
Est-il possible d'obtenir un délégué à exécuter sur un thread spécifique?
Dire que j'ai:
CustomDelegate del = someObject.someFunction;
Thread dedicatedThread = ThreadList[x];
Puis-je avoir un ensemble cohérent d'arrière-plan à long thread en cours d'exécution et d'appeler mon propre délégués à chaque fois que j'en ai besoin. Il doit être le même thread à chaque fois.
[Modifier]
La raison pour laquelle je veux qu'il soit sur un thread dédié est temps que je inten pour exécuter le délégué sur elle et de suspendre le fil après y
millisecondes, et reprendre le fil quand je lance un autre délégué. Je vois que ce n'est pas possible. Je vais avoir un délégué de la file d'attente et de laisser la fonction principale du thread de lecture et d'exécution.
À clarifier avec un exemple concret, j'ai un système de jeu avec un tas de joueur de threads. Je voudrais que chaque playerthread pour exécuter des gestionnaires d'événement pour les événements de jeu. Si les gestionnaires d'événements prennent trop de temps, j'aimerais être capable de mettre en pause joueur jusqu'à ce que le prochain événement, par la suspension de son fil.
Donc d'avoir un thread dédié, sur lequel je peux exécuter plusieurs gestionnaires d'événements que je peux mettre en pause un joueur en particulier de l'IA dans le cas où il est devenu buggé ou prend trop de temps.
OriginalL'auteur Raynos | 2010-08-13
Vous devez vous connecter pour publier un commentaire.
Je pense que la meilleure solution est d'utiliser
Task
des objets et de la file d'attente à un StaThreadScheduler de l'exécution d'un thread unique.Sinon, vous pouvez utiliser le
ActionThread
dans Nito.Async pour créer un normal avec du fil intégré dans la file d'attente deAction
délégués.Cependant, aucune de celles-ci s'adresse directement à un autre besoin: la capacité de "pause" d'une action et continuer avec un autre. Pour ce faire, vous aurez besoin de les arroser "les points de synchronisation" tout au long de chaque action et de disposer d'un moyen de sauvegarder son état, re-file d'attente, et de continuer avec la prochaine action.
De toute cette complexité est très près de l'approche d'une thread système de programmation, donc je vous recommande de prendre du recul et de faire plus d'une re-conception. Vous pourriez permettre à chaque action soit mis en file d'attente à la
ThreadPool
(je vous conseille juste d'avoir chacun unTask
objet). Vous aurez toujours besoin de l'arroser "les points de synchronisation", mais au lieu de sauver l'état et re-file, vous aurez juste besoin de faire une pause (bloc).Un mot d'avertissement: il est possible (voire probable) pour provoquer des blocages accidentellement, par la suspension/reprise de threads. Si possible, changer le code externe. Si ce n'est pas possible, alors envisager l'utilisation de priorités des threads au lieu de suspendre/reprendre.
OriginalL'auteur Stephen Cleary
Malheureusement, il n'y a vraiment rien de construit dans à faire sur n'importe quel générique fil. Vous pouvez accomplir cela en créant une classe qui encapsule un Thread et met en œuvre ISynchonizeInvoke.
Une approche simple est de créer un événement file d'attente de traitement sur le thread dédié comme LBushkin mentionne. Je vous suggère d'utiliser un
Queue<Action>
classe et appel à l'Action de déléguer directement. Vous pouvez réaliser la plupart des tâches que vous auriez besoin d'aide délégué anonyme actions.Enfin, juste un mot d'avertissement, je vous suggère d'utiliser un Sémaphore ou EventWaitHandle au lieu de Fil.Dormir sur le thread dédié. Il est nettement plus convivial que de l'exécution de votre arrière-plan de la boucle, encore et encore lorsque ses inutiles.
Je suis d'accord avec l'avertissement sur
Thread.Sleep
; toutefois, les op doivent mettre en œuvreSynchronizationContext
plutôt que l'ancienneISynchronizeInvoke
.OriginalL'auteur Justin Breitfeller
Normalement, je dirais juste à l'aide d'un le pool de threads ou
BackgroundWorker
de classe, mais cela ne garantit pas que le travail va se produire sur n'importe quel fil. On ne sait pas pourquoi vous vous souciez le thread qui exécute les travaux, mais en supposant qu'il n'est en quelque sorte la matière ...Vous auriez à passer le
Delegate
objet à travers une sorte de mémoire partagée, comme une file d'attente. Le thread d'arrière-plan aurait pour regarder cette file d'attente, tirez les délégués, lorsqu'ils existent, et de les exécuter.Si il s'avère que le pool de threads est acceptable pour exécuter votre code, vous pouvez toujours utiliser le
BeginInvoke
méthode de la délégué pour le faire:OriginalL'auteur LBushkin
Pour les threads que vous créez, vous pouvez uniquement spécifier le délégué ThreadStart lorsque vous les créez. Il n'y a aucune disposition pour l'injection d'un autre délégué dans un thread créé. Le Pool de Threads est différente en ce qu'elle permet de soumettre des délégués précédemment créé threads qu'il commence en votre nom.
Il n'est pas clair quel est le problème que vous essayez de résoudre. Qu'essayez-vous de réaliser (ou à éviter) en essayant d'exécuter plusieurs délégués sur un fil?
OriginalL'auteur Ed Power
Voici le modèle que j'ai mis en place pour faire quelque chose sur un thread spécifique. Un avantage de ceci est que le thread spécifique peut être commencé avant ou après le blocage des appels pour des travaux sont réalisés. C'était pour un objet COM wrapper appelé Watin pour manipuler des instances d'Internet Explorer qui est extrêmement sensible au contexte. Il pourrait être élargi de manière à supprimer la
Thread.Sleep()
, éventuellement avec uneAutoResetEvent
, ce qui aurait considérablement améliorer les performances dans certaines situations.L'idée de ce modèle était de Justin Breitfeller, Stephen Cleary, et LBushkin réponses.
OriginalL'auteur fartwhif