Question

J'ai une dll WPF qui contient un certain nombre de classes Window et expose les méthodes qui affichent ces fenêtres.

J'ai également un projet WinForms distinct qui appelle l'une de ces méthodes dans le projet WPF dans la méthode DoWork d'un composant BackgroundWorker.

Sur la ligne de code qui instancie une fenêtre WPF, j'obtiens l'erreur d'exécution suivante:

  

Le thread appelant doit être STA, car de nombreux composants d'interface utilisateur en ont besoin.

Une recherche google m'a permis de cette discussion . (Il s'avère que Jon Skeet répond aux questions sur d'autres sites en plus de Stack Overflow!). Il a créé un lien vers cet article , qui indique

  

Le composant BackgroundWorker fonctionne bien avec WPF ...

Cet article mentionne également l'utilisation de la classe DispatcherObject, mais je ne comprends pas comment le faire fonctionner et je préfère simplement continuer à utiliser mon composant BackgroundWorker.

Comme test, j’ai créé le code suivant pour reproduire l’erreur. Dans la bibliothèque de classes WPF, voici le code dans Window1.xaml.vb

Partial Public Class Window1

    Public Shared Function ShowMe() As Boolean?
        Dim w = New Window1 'Error appears on this line.
        Return w.ShowDialog()
    End Function

End Class

Dans l'application WinForms, voici le code dans Form1.vb

Imports System.ComponentModel

Public Class Form1

    Private WithEvents worker As BackgroundWorker
    Private Sub doWord(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles worker.DoWork
        WpfLibrary.Window1.ShowMe()
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        worker = New BackgroundWorker
        worker.RunWorkerAsync()
    End Sub
End Class

Même si le composant BackgroundWorker est placé dans Window1.xaml.vb, la même erreur se produit. Cet article est donc faux et je ne peux pas vraiment utiliser BackgroundWorker avec WPF? Ou dois-je faire autre chose pour que cela fonctionne?

Si BackgroundWorker ne fonctionne pas, comment puis-je remplacer le code dans Form1.vb ci-dessus pour utiliser un répartiteur à la place?

Était-ce utile?

La solution

Vous pouvez utiliser un travailleur d'arrière-plan avec WPF, ce n'est pas votre problème.

Votre problème est que vous ne pouvez effectuer aucune tâche mettant à jour l'interface utilisateur en dehors du thread principal de l'interface utilisateur dans une application winform ou WPF et que la méthode DoWork de BackgroundWorker s'exécute dans un autre thread.

Par conséquent, vous devez ouvrir la nouvelle fenêtre en dehors du fil d’arrière-plan de BackgroundWorker, avant de démarrer BackgroundWorker ou dans son événement RunWorkerCompleted.

Sans connaître le code qui entoure l'appel pour ouvrir la fenêtre, il m'est difficile de vous conseiller, mais j'espère que cela vous orientera dans la bonne direction.

Autres conseils

Votre agent peut également créer son propre thread, le marquer comme STA, puis appeler Thread.Join () pour attendre la fin de celui-ci. Vous pourrez alors créer et afficher la fenêtre sur votre nouveau thread (notez cependant qu'aucun autre thread ne pourra interagir avec celle-ci sans utiliser le répartiteur).

Exemple en C #:

Thread workerThread = new Thread(ShowMyWindow);
workerThread.SetApartmentState(ApartmentState.STA);
workerThread.Start();
workerThread.Join();

Et ensuite:

private void ShowMyWindow()
{
    WpfLibrary.Window1.ShowMe()
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top