Pregunta

Estoy usando un AutoResetEvent donde múltiples llamadas Set se pueden hacer en un evento (manejo de excepciones). Hay momentos en que un juego extra se llama, por lo tanto cuando el código realiza una segunda llamada en un evento WaitOne, que sólo pasa a través de la puerta, porque ya se ha abierto.

La solución es llamar Restablecer justo antes de la WaitOne. ¿Hay una solución más limpia o se trata de la única manera de hacerlo? Ejemplo código:

private void DoSomeWork()
{
    Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
    thrd.Start();

    //mEvt.Reset();
    mEvt.WaitOne();

    //continue with other stuff
}

private void DoSomeOtherStuff()
{
    /* lots of stuff */

    mEvt.Set();
}

private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
   mEvt.Set();
}

Una vez que se controla la excepción, necesito llamar DoSomeWork de nuevo, pero desde Conjunto llamada podría en múltiples excepciones (o excepciones relanza), el WaitOne sólo fluye a través.

Mi solución es llamar siempre antes del reinicio WaitOne. ¿Es esta la solución approriate, mal diseño, o hay otro tipo de evento que va a manejar esta situación?

EDIT:. Me acabo de mudar el reinicio comentado (solución propuesta) junto al evento

¿Fue útil?

Solución

Mi preocupación sería que si usted llama Reset () antes de WaitOne (), que está en problemas si no hay Set () se llama cada vez. Esto puede ocurrir si se llama Set (), después haga clic en Reset () inmediatamente después, antes de llegar a WaitOne (). Incluso si usted está llamando Set () dos veces, no hay garantía de que no va a llamar a reset () después de que ambos, bloqueando el hilo con ningún mecanismo para la liberación.

Lo ideal sería tener un bloque try..catch..finally, y llamar al Set () en el bloque finally, y no tener el control de excepciones propagación a través de métodos. Hace que el trabajo para usted?

Hans es correcto que en este escenario, el multihilo es innecesaria. Mis preocupaciones sólo se aplican si usted está realmente multihilo con sus llamadas a WaitOne ().

También me preocupa que usted está llamando conjunto más de una vez ... ¿Eso quiere decir que cuando el primer juego se llama, el recurso realmente debe permanecer bloqueado? Si todavía es capaz de golpear Set () una segunda vez, para mí que dice que todavía está ejecutando el código que funciona con recursos compartidos. En cuyo caso no desea que la llamada a WaitOne () para desbloquearse.

También tenga en cuenta, desde el MSDN:

  

No hay ninguna garantía de que cada llamada al método Set lanzará un hilo. Si dos llamadas están demasiado juntos, de manera que la segunda llamada se produce antes de que un mensaje ha sido puesto en libertad, sólo un hilo es liberado. Es como si la segunda llamada no sucedió.

En cualquier caso, parece que el código sea debe ir a la ruta de lanzar una excepción, o correr hasta el final, pero no ambos. ES DECIR. usted no debe estar llamando Set () dos veces.

Otros consejos

Esto no es un problema real, el WaitOne () llamará automáticamente restablece el evento. Después de todo, que utilizó un AutoResetEvent, no un ManualResetEvent. frase clave aquí es de reinicio automático.

Al verlo vapor a través de la llamada WaitOne () es bastante normal también. Tienes una buena CPU de múltiples núcleos, el hilo se inició de inmediato cuando llamó Inicio () y no toma sólo unos pocos microsegundos a hacer el trabajo. Milisegundos, lo que sea, más rápido que un abrir y cerrar de ojo.

Tal vez más al punto, simplemente no necesita un hilo aquí. Iniciar uno, luego esperar a que termine no tiene sentido. Sólo tiene que llamar la DoSomeOtherStuff () directamente.

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