3 votes

des limitations API déconcertantes

L'API ne prend pas officiellement en charge le threading (voir ci-dessous) ni la fermeture d'un document actif. Cela dit, une solution de contournement pour fermer un document actif consiste à appeler...

SendKeys.SendWait("^{F4}");

...d'un fil séparé. Cela fonctionne bien, sauf que je dois ouvrir et fermer plusieurs documents en boucle. Si je place un quelconque code après thread, il sera exécuté avant la fermeture du document précédent. J'ai essayé un certain nombre de méthodes standard de rappel de threading, notamment...

Task.Factory.StartNew(() =>

ThreadPool.QueueUserWorkItem(new WaitCallback

AutoResetEvent.WaitOne()

sans succès. Et Thread.Sleep() ne fait que bloquer l'erreur/crash. Quelqu'un a-t-il une idée ?

"Les internes de Revit n'utilisent le multitraitement qu'à quelques endroits isolés. Aucun de ces endroits n'englobe actuellement le code de l'API Revit, ou une partie de celui-ci. Autodesk ne recommande donc pas d'effectuer des appels à l'API Revit à partir de threads parallèles exécutés simultanément. Il se peut qu'une partie de l'API Revit soit suffisamment isolée pour pouvoir être exécutée avec succès à partir d'un tel code de threads dans un environnement de test ; cela ne doit pas être considéré comme une garantie que le même code source fonctionnera pour n'importe quel modèle ou situation, ou qu'une modification future de Revit n'entraînera pas l'arrêt du fonctionnement de ce code."

    public void OpenFile()
    {
        for (int i = 0; i < 3; i++)
        {
            uiApp.OpenAndActivateDocument(TargetPath(i));

            ThreadPool.QueueUserWorkItem(CloseDocProc);

            //any code here at all opens the next doc without closing the last
        }            
    }

    public void CloseDocProc(object stateInfo)
    {
        SendKeys.SendWait("^{F4}");

        //can run code here
    }

1voto

topofsteel Points 1197

Le problème était l'enfilage, comme ils l'avaient dit. En utilisant n'importe quelle méthode de rappel, il se figeait à ce moment-là. Et vous ne pouvez faire qu'un nombre limité de choses dans le thread, il ne me laissait pas ouvrir un document, quoi qu'il arrive !

La réponse était d'utiliser une minuterie à un seul fil.

System.Windows.Forms.Timer;

J'appelais ma méthode Open() toutes les 10 secondes environ, j'arrêtais le minuteur et j'exécutais la dernière partie du code lorsqu'un compteur atteignait un certain point.

1voto

Maxence Points 5619

Je ne sais pas si cela peut faire l'affaire, mais vous pouvez peut-être utiliser cette technique : http://adndevblog.typepad.com/autocad/2012/06/use-thread-for-background-processing.html

C'est pour AutoCAD, mais je pense que ça pourrait fonctionner avec Revit. L'API de Revit, comme celle d'AutoCAD, ne supporte pas le multithreading. Vous ne devez appeler les fonctions de l'API qu'à partir du thread principal.

Vous avez besoin de marshaler l'appel vers le thread principal. Le moyen le plus simple d'y parvenir est de créer un objet System.Windows.Forms.Control sur le thread principal et d'appeler son Invoke() depuis le thread séparé où vous fermez le document.

Vous pouvez également utiliser l'événement de veille d'une manière créative...

0voto

Randall Points 124

Créez une machine d'état dans le gestionnaire d'événement idle de votre application qui interagit avec votre thread et qui gère les appels Revit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X