2010-01-19 9 views
1

J'ai une classe utilitaire avec thread de travail avec des conditions de sortie simples. J'utilise cette classe dans mon application. Le thread de travail est créé et démarré dans le constructeur de la classe.Worker thread et Dipose()

class MyClass 
{ 
    Thread _thread; 

// unrelevant details are omitted 
void WorkerThreadRoutine 
{ 
    while(_running) 
{ 
    // do some useful background work here 
} 
} 
} 

Ma question est QUAND dois-je définir _running = false. En C++ avec déterminisme la vie de désallocation des ressources est facile - J'utilise des destructeurs d'objets et ne s'en soucie pas.

Je voudrais écrire quelque chose comme

~MyClass() 
{ 
    _running = false; 
} 

En C# il pas dans le sens Destructeurs C++. Dois-je écrire une fonction Dispose() ici et utiliser IDisposable? Je peux bien sûr fournir une fonction Stop(). Mais quand dois-je l'appeler? Est-il possible d'appeler automatiquement ma fonction Stop?

Quel est le bon motif ici? J'ai beaucoup d'intensions MyClass dans mon application.

Maintenant, mon application se bloque à la sortie.

Répondre

1

En C++, vous appelez normalement explicitement l'opérateur de suppression. Ce n'est pas différent d'appeler explicitement une méthode Stop() en C#.

Le compilateur C++ peut générer automatiquement l'appel d'opérateur de suppression si votre objet est une variable locale d'une méthode. Google Maps est bien IDisposible en C# avec l'instruction à l'aide:

void SomethingSlow() { 
    using (var obj = new MyClass()) { 
    // etc.. 
    } 
} 

class MyClass : IDisposable { 
    private ManualResetEvent mStop = new ManualResetEvent(false); 
    public Dispose() { 
    mStop.Set(); 
    } 
    // etc... 
} 

Votre fil ne probablement arrête pas en ce moment parce que vous avez oublié de déclarer le champ _running comme volatile. L'utilisation d'un événement peut aider à éviter de tels problèmes. Vous pouvez définir la propriété IsBackground du thread sur true pour empêcher le thread de suspendre la terminaison de votre programme. C'est un pansement, pas une solution.

2

La raison pour laquelle votre application se bloque est que les nouveaux threads sont créés en tant que threads de premier plan par défaut. Le CLR gardera votre processus en vie tant que vous avez des threads de premier plan en cours d'exécution.

Pour se débarrasser du thread, il suffit de quitter le code en cours d'exécution. Cela rendra le thread disponible pour le nettoyage et une fois qu'il a été arrêté, le processus pourra également se fermer (en supposant que vous n'avez aucun autre thread de premier plan en cours d'exécution).