Pregunta

Según la documentación, WAITHANDLE IN .NET debe ser eliminado explícitamente / implícitamente.Sin embargo, tengo problemas para lograr esto para la siguiente tarea de sincronización básica:

  • Se está ejecutando una tarea que consume mucho tiempo en un hilo.
  • El hilo principal espera que la tarea se complete por un período de tiempo predefinido.El hilo principal debe proceder si a.La tarea se completa o b.El tiempo de espera ocurrió.

Aquí, mi intento de usar un objeto AutoresElevent:

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();
    }
}

Hay una condición de raza obvia en la que los tiempos de espera del hilo principal hacia afuera y disponen el objeto de la manija de espera, lo que causa la excepción de ObjectSIsPositedException.¿Hay alguna otra forma de que establezco esto para que el asa esté dispuesta correctamente y sin causar la excepción?

¿Fue útil?

Solución

Claro, no hay una forma decente de hacer esto. Haz la nota al frente de que te pintaste en esa esquina, lo que esencialmente dejó un hilo corriendo salvaje, nada particularmente agradable en eso.

Pero se está enfocando en el problema mucho más pequeño. La clase de hilo en sí ya es un cerdo de recursos, consumiendo un megabyte de VM y cinco objetos de sincronización. Pero no tiene un método de disposición (). Este fue un diseño valiente, simplemente no hay una forma decente de llamar al método.

La eliminación es Opcional , nada que ocurra dramático cuando no lo llame. La clase tiene su espalda, tiene un finalizador que garantiza que se publique el recurso del sistema operativo nativo. Que hará correr, eventualmente, simplemente no tan rápido como quieras.

Compare esto a una clase con un diseño menos valiente, la clase de trabajo tiene un método Dispose (). Que, como el hilo, es casi tan difícil de llamar. El La guía de los gurus .NET es para Simplemente no se moleste.

mismo aquí.

Otros consejos

El Waithandel está dispuesto porque su alcance usando invoca un nuevo hilo y se devuelve de inmediato, lo que hace que el Waithande se deseche.

Lo que debe hacer es que se deseche explícitamente después de que finalice su trabajo en lugar de su declaración usando:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top