2011-07-15 4 views
5

Je suis en train de créer un deuxième thread avec dispatcher afin que je puisse avoir le répartiteur principal (pour l'interface utilisateur) complètement sans stress et que l'interface utilisateur réponde en permanence..NET Create New Dispatcher

Maintenant, je pourrais créer plusieurs threads pour chaque sous-sol (ou void en C#), mais n'est-il pas possible pour moi de créer un nouveau thread et d'attraper son répartiteur, et de l'invoquer? C'est ce que j'ai fait:

Private CheckLoopThread As New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf CheckLoop)) 

CheckLoopThread.Priority = System.Threading.ThreadPriority.Lowest 
CheckLoopThread.Start() 
Dim Test As Windows.Threading.Dispatcher = Windows.Threading.Dispatcher.FromThread(CheckLoopThread) 

Cependant, la variable "Test" est après l'exécution "Nothing". Comment est-ce possible? Est-ce l'autre façon de créer un second répartiteur?

Les réponses sont appréciées sous n'importe quelle forme .NET. Visual Basic ou C#. Je travaille dans VB.NET WPF sur le framework .NET 4.0.

Merci d'avance.

+0

Assurez-vous que CheckLoopThread ne se termine pas immédiatement après le démarrage (si le fil exécute une procédure CheckLoop qui ne prend pas de temps à exécuter). –

+0

La boucle de contrôle contient une boucle qui ne s'arrête pas. –

Répondre

10

Dispatcher.FromThread ne créera pas de Dispatcher et renverra null si un Dispatcher n'a pas déjà été créé pour le thread. Pour créer un Dispatcher pour un thread, vous devez accéder au Dispatcher.CurrentDispatcher au moins une fois sur votre CheckLoopThread. Comme il est dit sur MSDN pour Dispatcher.CurrentDispatcher:

Si un répartiteur n'est pas associé au thread courant, un nouveau Dispatcher sera créé. Ce n'est pas le cas avec la méthode FromThread . FromThread retourne null s'il n'y a pas un répartiteur associé au thread spécifié

+0

Merci beaucoup! C'était en effet cela. +1 Pour vous. –

5

Je crée en fait un grand nombre de ces répartiteurs, je suppose que la bonne façon est quelque chose le long des lignes suivantes:

object theLock = new object(); 
Dispatcher dispatcher = null; 

lock (theLock) 
{ 
    new Thread(new ThreadStart(() => 
    { 
     lock (theLock) 
     { 
      dispatcher = Dispatcher.CurrentDispatcher; 
      Monitor.Pulse(theLock); 
     } 
     Dispatcher.Run(); 
    })).Start(); 

    Monitor.Wait(theLock); 
} 

dispatcher.Invoke(...); 

Cela semble compliqué avec tout le verrouillage, mais en théorie, la méthode Start() peut retourner avant que dispatcher ne soit réellement définie, donc un appel vers cette dernière peut aboutir à un NullReferenceException sans les verrous.

+0

Cela l'a fait pour moi. Merci! – aclave1

7

Pourquoi le verrouillage?

Je préfère:

Dispatcher myDispatcher = null; 

ManualResetEvent dispatcherReadyEvent = new ManualResetEvent(false); 

new Thread(new ThreadStart(() => 
{ 
    myDispatcher = Dispatcher.CurrentDispatcher; 
    dispatcherReadyEvent.Set(); 
    Dispatcher.Run(); 
})).Start(); 

dispatcherReadyEvent.WaitOne(); 

myDispatcher.Invoke(...); 
+1

Très vrai, même si je ne suis pas sûr si l'implémentation sous-jacente est la même. – mycroes