Détecter qu'un ThreadPool WorkItem est terminé / en attente de fin
-
03-07-2019 - |
Question
Pour une raison quelconque, le QueueWorkItem
de de ThreadPool
ne renvoie pas de IAsyncResult
ou un autre descripteur de l'élément de travail, ce qui permettrait attendre que ce soit terminé. Il existe des méthodes RegisterWait ...
, mais vous devez passer un WaitHandle
et leur création coûte cher (voir la documentation IAsyncResult
, qui vous conseille de retarder la création d'un WaitHandle
jusqu'à ce que demandé). La bibliothèque parallèle de tâches corrigera ce manque, mais il faut attendre longtemps avant que cela soit disponible. Alors, y at-il des problèmes avec cette conception:
public class Concurrent<T> {
private ManualResetEvent _resetEvent;
private T _result;
public Concurrent(Func<T> f) {
ThreadPool.QueueUserWorkItem(_ => {
_result = f();
if (_resetEvent != null)
_resetEvent.Set();
});
}
public WaitHandle WaitHandle {
get {
if (_resetEvent == null)
_resetEvent = new ManualResetEvent(_result != null);
return _resetEvent;
}
...
EDIT: J'ai posé une question de suivi sur les préoccupations qui surviennent lors de l’utilisation de délégués asynchrones au lieu du ThreadPool .
La solution
Eh bien, vous avez une condition de concurrence entre aller chercher WaitHandle et le régler. Voulez-vous vraiment que l'appelant attende pour toujours s'il lui arrive d'être un peu en retard?
Vous devriez probablement effectuer un verrouillage approprié et conserver un " j'ai terminé " Indiquez que si vous créez le WaitHandle une fois terminé, vous le définissez avant de le renvoyer.
J'écrirais aussi personnellement une méthode fabrique statique plutôt que d'utiliser simplement un constructeur public - ou en ferais un "créer et puis , démarrer explicitement" et modèle. Mettre en file d'attente l'élément de travail dans le constructeur me semble bizarre.
Autres conseils
Pourquoi n'utilisez-vous pas un délégué asynchrone, comme présenté ici:
http://msdn.microsoft.com/en-us/library /h80ttd5f.aspx
Cela rendrait Concurrent obsolète, non?