2009-07-16 4 views
0

Je possède ce code:Compact Framework 2.0: Comment arrêter un thread quand un objet est éliminé?

Thread t = new Thread(() => UpdateImage(origin)); 
t.Name = "UpdateImageThread"; 
t.Start(); 

Ce code est créé sur un contrôle personnalisé. Je veux arrêter ce thread (s'il est en cours d'exécution) quand l'objet va être éliminé.

Ce contrôle personnalisé a la méthode suivante:

void IDisposable.Dispose() 
{ 
    /* My own code */ 
    base.Dispose(true); 
} 

Je pense que c'est l'endroit idéal pour mettre le code, mais:

Comment puis-je savoir est le fil est en marche? Comment puis-je prendre une référence pour le fil et l'arrêter? Par ailleurs, UpdateImage appelle un service Web, donc je pense qu'il attend toute sa vie. Comment puis-je terminer cette attente?

Merci!

Répondre

1

Cela dépend beaucoup de ce que fait UpdateImage() et de la façon dont il fait face à l'image étant disposée alors qu'il est encore actif. Si UpdateImage() est votre code et contient une boucle, vous pouvez lui dire d'arrêter (en utilisant un champ comme _stopping). Si ce n'est pas le cas, la meilleure chose à faire est de ne rien faire - dans le cas rare de jeter le contrôle pendant que l'image est encore en train de se mettre à jour, vous prenez la peine de la laisser au GC. A propos de l'obtention du thread: En enregistrant la référence quand et où vous le créez, par exemple dans le membre privé _updateThread.

Maintenant l'arrêt (l'abandon) du thread est une (très) mauvaise idée.

Vous aurez besoin d'un indicateur, comme

private bool _stopping = false; 

Et il est à la méthode UpdateImage() pour réagir à _stopping == true et arrêter avec ce qu'il fait.

Votre Dispose() peut alors utiliser

_stopping = true; 
_updateThread.Join() 
+0

méthode UpdateImage fait un service Web demande et je ne sais pas comment l'annuler. Peut-être le faire asynchrone ... – VansFannel

0

Je suggère de remplacer la méthode Dispose dans votre contrôle personnalisé. Là vous avez la référence de votre fil et vous pouvez appeler .Join() par exemple ...

1

Enregistrez votre variable de fil 't' afin de pouvoir la réutiliser plus tard.

Au sein de votre méthode Dispose vous voulez quelque chose comme:

void IDisposable.Dispose() 
{ 
    if(t.IsRunning) 
    { 
     cancelThreads = true; // Set some cancel signal that the thread should check to determine the end 
     t.Join(500); // wait for the thread to tidy itself up 
     t.Abort(); // abort the thread if its not finished 
    } 
    base.Dispose(true); 
} 

Vous devez être prudent fils abandon cependant, assurez-vous que vous placez la section de code critique dans les régions qui ne permettra pas le fil d'arrêter avant qu'il ait terminé, et attraper ThreadAbortExceptions pour ranger tout si elle est abandonnée.

Vous pouvez faire quelque chose comme ça dans les fils commencer méthode

public void DoWork() 
{ 
    try 
    { 
     while(!cancelThreads) 
     { 
     // Do general work 

     Thread.BeginCriticalRegion(); 
      // Do Important Work 
     Thread.EndCriticalRegion(); 
     } 
    } 
    catch(ThreadAbortException) 
    { 
     // Tidy any nastiness that occured killing thread early  
    } 
} 
+0

Et ... Qu'en est-il d'annuler la demande de service Web? – VansFannel

+0

IsRunning, BeginCriticalRegion et EndCriticalRegion ne sont pas compatibles avec Compact Framework 2.0. – VansFannel

+0

Mes excuses, je n'ai pas repéré la partie compacte. Oops. Dans ce cas, disposez simplement d'un indicateur que vous définissez pour chaque thread (vous pourriez avoir besoin d'une classe wrapper personnalisée pour le faire). Les régions critiques Begin et End, assurez-vous simplement que tout ce qui est critique est valide dans l'exception ThreadAbortException. – Ian

Questions connexes