Question

Selon la documentation, WAITHANDLE IN .NET doit être explicitement / implicitement disposé.Cependant, j'ai du mal à atteindre cet objectif pour la tâche de synchronisation de base suivante:

  • Une tâche fastidieuse est en cours d'exécution sur un fil.
  • Le fil principal attend la tâche de terminer pour une période de temps prédéfinie.Le fil principal doit continuer si un.La tâche est complétée ou b.le délai d'attente s'est produit.

Ici, ma tentative d'utilisation d'un objet AutoresetEvent:

using(var waitHandle = new AutoResetEvent(false)){
    var worker = new Thread(() =>
    {
        try
        {
            TimeConsumingTask();
            waitHandle.Set(); //throws System.ObjectDisposedException: Safe handle has been closed
        }
        catch (Exception e)
        {...}
    }) {IsBackground = true};
    worker.Start(); //start worker

    const int waitTimeInMs = 5000; 
    var signaled = waitHandle.WaitOne(waitTimeInMs);//block main thread here. 
    if (!signaled)
    { //if timed out
       worker.Interrupt();
    }
}

Il y a une condition de course évidente où les temps d'attente du fil principal et disposent de l'objet de la poignée d'attente qui provoque une exception d'objetDisposedException.Y a-t-il une autre manière que je l'ai configurée pour que la poignée soit correctement disposée et sans causer l'exception?

Était-ce utile?

La solution

Bien sûr, il n'y a pas de moyen décent de le faire. Notez le devant que vous avez peint dans ce coin en laissant essentiellement un fil qui coule sauvage, rien de particulièrement gentil à ce sujet.

Mais vous vous concentrez sur le problème beaucoup plus petit. La classe de fil elle-même est déjà une ressource porc, consommant un mégaoctet de VM et cinq objets de synchronisation. Mais cela n'a pas de disposition (). C'était une conception courageuse, il n'y a tout simplement pas de moyen décent d'appeler la méthode.

disposer est facultatif , rien qui dramatique se produit lorsque vous ne l'appelez pas. La classe a votre dos, il dispose d'un finaliseur qui garantit que la ressource du système d'exploitation indigène sera libérée. Qui sera courir, finalement, pas aussi vite que vous le souhaitez.

Comparez ceci à une classe avec un design moins courageux, la classe de tâches dispose d'une méthode Dispose (). Ce qui, comme le fil, est presque aussi difficile à appeler. Guidage de la gourous .NET est de tout simplement pas déranger.

même ici.

Autres conseils

Le WAITHANDLE est mis à disposition car votre utilisation d'une portée invoque un nouveau fil d'un retour immédiatement, ce qui entraîne le disposer du dispositif de disparition.

Ce que vous devriez faire est explicitement appeler Disposer après avoir terminé votre travail au lieu de votre instruction Utilisation:

waitHandle.WaitOne(waitTimeInMs);
if (!signaled)
{ //if timed out
   worker.Interrupt();
}
waitHandle.Dispose();

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top