L'ajout d'un enfant à Viewport3D de manière asynchrone donne & # 8220; Cette API a été utilisée avec des arguments provenant d'un contexte incorrect. & # 8221;
-
05-07-2019 - |
Question
Lorsque j'essaie d'ajouter du contenu 3D à Viewport3D de manière asynchrone, le résultat est "On a accédé à cette API avec des arguments provenant d'un contexte erroné". dans une TargetInvocationException.
Le contenu 3D est généré à partir des données d'un appareil de numérisation 3D. La communication et les calculs nécessaires à cet effet sont effectués dans un thread séparé. D'abord, j'ai essayé d'accéder à viewport3D à partir de ce fil. J'ai réalisé que cela devrait être fait par le GUI-thread, donc maintenant j'utilise ce code:
ModelVisual3D model = new ModelVisual3D();
model.Content = scanline;
DispatcherOperation dispOp = this.viewport.Dispatcher.BeginInvoke(
new AddModelDelegate(StartAddModel), model);
}
private void StartAddModel(ModelVisual3D model)
{
this.viewport.Children.Add(model);
//model is not in the context of this current thread.
//Throws exception: "This API was accessed with arguments from the wrong context."
}
private delegate void AddModelDelegate(ModelVisual3D model);
Il semble que l'objet nommé "modèle" n'est pas dans le contexte du fil actuel. Comment puis-je réparer cela? Existe-t-il un moyen d’intégrer le modèle dans le contexte de Dispatcher? Ou est-ce que cette façon de faire n’est pas la bonne façon d’aller ici?
La solution
Cela se produit chaque fois que vous générez / modifiez des objets de scène à ajouter à Viewport, à partir d'un autre thread que celui sur lequel Viewport a été instancié. Il y a un travail simple autour. Encapsulez le code qui met à jour les objets Viewport dans une fonction. Insérez l'extrait suivant et vous avez terminé.
private delegate void MyFunctionDelegate();
void MyFunction()
{
if(!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.Invoke(new MyFunctionDelegate(MyFunction));
return; // Important to leave the culprit thread
}
.
.
.
this.Viewport3D.Children.Remove(model);
MyModifyModel(model);
this.Viewport3D.Children.Add(model);
}