11
votes

La bibliothèque parallèle de la tâche .NET 4 peut-elle utiliser des objets COM?

C'est un "est-ce possible, et si oui, pouvez-vous me donner un exemple rapide parce que je ne trouve pas en ligne?" genre de question.

J'ai un certain nombre de processus complètement séparés (c'est-à-dire "" embarrassant parallèle ") que je veux exécuter en parallèle à l'aide de la bibliothèque parallèle de tâche dans la structure .NET 4 en utilisant c #. Certains de ces processus nécessitent l'utilisation de logiciels pouvant être accessibles via COM / OLE Automation.

Spécifiquement, il existe une boucle parallèle.Foreach () qui divise les tâches d'une liste d'éléments, appelant essentiellement une fonction différente à l'intérieur du parallèle.Foreach pour gérer le traitement (certaines de ces fonctions utilisent donc des bibliothèques COM. ).

est-ce possible? Merci.


1 commentaires

Cela ressemble à un candidat parfait pour un test rapide ... Essayez-le.


3 Réponses :


2
votes

C'est potentiellement possible, mais cela ne fonctionne pas non plus.

De nombreux objets COM nécessitent un filetage de l'appartement . Lorsque vous utilisez parallèle.Pour / foreach, vous exécutez sur le fichier threadpool .Net, qui ne dispose pas de la configuration de l'appartement. Cela peut fonctionner et peut pour certains objets COM, mais peut également provoquer des crashs et des exceptions étranges difficiles à suivre.


0 commentaires

18
votes

Il est 100% possible d'utiliser des objets COM avec le TPL. Bien que ce soit vrai que, par défaut, le TPL utilisera la norme .NET Threadpool, le TPL a un point d'extension via Le TaskScheduler Classe qui vous permet de fournir à votre propre planificateur qui peut expédier des travaux sur les threads que vous avez créés.

En cas d'utilisation d'objets COM, vous devez d'abord savoir si la classe COM nécessite un filetage STA ou un filetage MTA. Si le filetage MTA, il n'ya rien de spécial qui doit être fait car la classe COM peut déjà être utilisée à partir de n'importe quel fil aléatoire. Malheureusement, la plupart des objets COM classiques ont tendance à compter sur la filetage de STA et c'est à ce moment-là que vous auriez besoin d'utiliser une tâche TaskSchDuler de sorte que quel que soit le fil .net que vous utilisez depuis a été initialisé en tant que fil compatible STA .

tandis que Les tâches techniques ne sont pas exactement triviales pour écrire, ils ne sont pas vraiment difficiles à écrire non plus si vous avez une compréhension de base du filetage. Heureusement La bibliothèque d'extras parallelExtensions fournit déjà une classe StaksScheduler de sorte que vous ne faites pas ' t même besoin d'écrire quoi que ce soit. Il y a Un excellent article de blog ici par le PFX équipe qui discute de la mise en œuvre de et certains cas d'utilisation pour la classe StaStaskschéduler

essentiellement, vous voudrez initialiser un nouveau Stakscheduler comme Un statique quelque part sur l'une de vos classes, puis il suffit de commencer vos tâches spécifiant qu'ils sont programmés par cette instance. Cela ressemblerait à quelque chose comme ceci: xxx


2 commentaires

Très intéressant, je vais devoir regarder cela, merci! Pour référence, la fonctionnalité principale que j'essaie d'atteindre est l'exécution parallèle de plusieurs flux de travail dans R ( r-project.org ). Je vais faire rapport ici si je saisis quelque chose.


Merci exactement ce dont j'avais besoin.



0
votes

Certaines informations supplémentaires que je dois encore vérifier, mais cela peut être utile. Le planificateur de tâches par défaut utilisera le thread actuel pour effectuer une partie du travail, puis ajoutez des fils supplémentaires du pool de fil si nécessaire.

Cela pourrait causer des problèmes si vous partagez un objet COM lorsque vous faites parallèle. Par exemple, disons que votre fil principal est STA. Vous instaniez l'objet COM sur cela et utilisez Parallel.foreach pour effectuer des travaux où chaque thread essaie d'accéder à l'objet COM précédemment instancié. Je soupçonne que cela se casse et les tests initiaux semblent remonter. Dans ce scénario, je vois au moins quelques options:

  • En supposant que l'objet COM supporte le MTA, demandez au fil d'appel d'utiliser MTA. Cependant, cela peut ne pas être une option pour d'autres raisons. Par exemple, si l'application est une application de formulaires Windows, je pense que le principal () est requis pour avoir l'attribut STATHREAD.
  • Utilisez un planificateur de tâches alternatif telle que le StatutasScheduler mentionné par Drew. Vous pouvez avoir tous les threads STA ou utiliser un planificateur qui n'utilise pas le fil d'appel et exécutez tous les threads MTA.

0 commentaires