2011-06-01 1 views
1

Je souhaite ouvrir certaines fenêtres non modélisées (WPF) mais au moment où cela doit se produire, je suis sur un thread non STA. Donc, je commence un nouveau fil et les ouvre là-bas. Mais dès qu'ils sont ouverts, ils se referment. (Soit dit en passant. Le comportement de ces fenêtres doit être indépendante de la fenêtre principale. Donc, pas de propriété propriétaire est définie)Comment empêcher la fermeture de fenêtres non modales sur un nouveau thread STA

private void SomeMethod_OnA_NON_STA_Thread() 
{ 
    // some other work here 

    Thread ANewThread = new Thread(OpenSomeWindows); 
    ANewThread.SetApartmentState(ApartmentState.STA); 
    ANewThread.Start(); 
} 


private void OpenSomeWindows() 
{ 
    TestWindow T; 

    for (int i = 0; i < 3; i++) 
    { 
     T = new TestWindow(); 
     T.Show(); 
    } 
} 

Qu'est-ce que je fais mal ici?

Répondre

3

Si vous voulez que vos fenêtres à vivre, vous devez commencer la boucle de message après que vous les avez créés (sinon votre fil juste sortie et les fenêtres ont aucune chance de se rendre):

private void OpenSomeWindows() 
{ 
    for (int i = 0; i < 3; i++) 
    { 
     TestWindow T = new TestWindow(); 
     T.Show(); 
    } 
    Dispatcher.Run(); // <--------- 
} 

(Dans thread principal, la boucle de message est créé par le cadre pour vous)

PS. Je ne suis pas sûr que les fenêtres peuvent être déchets collectés, donc je garderais des références pour les quelque part:

List<TestWindow> windows = new List<TestWindow>(); 
for (int i = 0; i < 3; i++) 
{ 
    TestWindow t = new TestWindow(); 
    t.Show(); 
    windows.Add(t); 
} 
Dispatcher.Run(); 

P.P.S .: Peut-être que vous voulez que vos fenêtres s'exécutent dans le fil principal? En fait, vous pouvez le faire. Vous avez juste besoin de ce qui suit:

private void SomeMethod_OnA_NON_STA_Thread() 
{ 
    // some other work here 
    Application.Current.Dispatcher.Invoke(OpenSomeWindows); 
} 

private void OpenSomeWindows() 
{ 
    for (int i = 0; i < 3; i++) 
    { 
     TestWindow T = new TestWindow(); 
     T.Show(); 
    } 
    // this way, no Dispatcher.Run is needed 
} 
+0

Thx !!!!! Maintenant ça marche. Encore une fois je trouve que je dois lire plus sur cette chose de répartiteur. –

+0

Mais lisez la dernière mise à jour ... – Vlad

+1

Cette dernière itération: (Application.Current.Dispatcher.Invoke (OpenSomeWindows);) est (IMHO) la meilleure façon de traiter l'interface utilisateur à travers différents threads, surtout si vous essayez d'écrire quelque chose rapidement, et ne veulent pas avoir à apprendre ou réapprendre le filetage. Je sais que c'est mauvais, mais pour les prototypes et les petits projets, parfois vous voulez juste quelque chose qui fonctionne, ce que cela fait. –

0

Le fil meurt à la fin de la méthode d'appel. Faites ANewThread dans un champ (déclarez-le au niveau de la classe/du formulaire).

Questions connexes