2010-11-03 665 views
8

De acuerdo con la documentación de MSDN, Set() y Reset() en ManualResetEvent (o cualquier EventWaitHandle) devuelve un indicador booleano indicando si la operación fue exitosa o no.¿Cuándo puede ManualResetEvent.Set() devolver falso?

¿Bajo qué circunstancias puede esta llamada volverse falsa, y qué se supone que debo hacer si lo hace?

Respuesta

15

No estaba seguro de cómo responder esto y de ver muchos ejemplos de MSDN. El valor de devolución del conjunto se ignora, por lo que no debe ser importante o probable que suceda.

Pero eso no fue suficiente. Encendí mi VM y abrí Reflector para echarle un vistazo al código. ManualResetEvent no tiene Set pero hereda de EventWaitHandle que sí lo hace. Aquí está el código:

public bool Set() 
{ 
    bool flag = Win32Native.SetEvent(base.safeWaitHandle); 
    if (!flag) 
    { 
     __Error.WinIOError(); 
    } 
    return flag; 
} 

Dónde SetEvent ha sido importada desde Kernel32:

[DllImport("kernel32.dll", SetLastError=true)] 
internal static extern bool SetEvent(SafeWaitHandle handle); 

El WinIOError() llamada sólo llama GetLastWin32Error la que no le importa en realidad. Básicamente, esto significa que la llamada para devolver falso, algo bastante mal tendría que haber ocurrido en el código nativo de Win32.

Poniendo esta información junto con el hecho de que el código alojado en la documentación oficial de MSDN ignora el valor de retorno (¿por qué no? ¿Qué vas a hacer si falla el kernel?) Puedes ignorarlo tú mismo si quieres limpiarlo su lógica un poco o conseguirlo y registrarlo si eres especialmente pedante.

+2

Respuesta bien investigada. +1 – spender

+0

Gracias! Fue una pregunta interesante y me hizo sentir curiosidad. –

+1

Gracias Erik. Inspirado por tu trabajo, hice lo mismo y abrí Reflector. Parece que WinIOError() arrojará siempre una excepción que intente representar el código de error de Win32 en el mundo .NET, lo que tiene sentido, pero aún no explica por qué la llamada tiene un valor de retorno. – SoftMemes

0

No estoy seguro de que basta con registrar el error y continuar con la ejecución. El resultado falso de Set() puede generar un comportamiento incorrecto en la sincronización de hilos gestionada por los controladores de espera. Eso es multithreading ... Mi visión del manejo del falso Set() result - throw exception, que probablemente en la mayoría de los casos no se pueda manejar.

Cuestiones relacionadas