2011-05-28 12 views
47

¿Hay alguna razón práctica por la que el equipo .NET decidió no admitir Boolean en la operación Interlocked.Exchange?¿Por qué Interlocked.Exchange no es compatible con el tipo booleano?

Uno de los ejemplos de uso es cuando desea garantizar que algún código se ejecute solo una vez y desea usar un indicador booleano para eso.

+3

Por supuesto, solo puede usar un 'int' y' if (Interlocked.CompareExchange (ref value, 1, 0) == 0) {...} '- no responde * por qué * por supuesto. .. o tal vez más fácil - 'Lazy ': http://msdn.microsoft.com/en-us/library/dd642331.aspx –

+0

Buena pregunta, esto se ha informado a Microsoft muchas veces en los últimos años. No he visto una razón satisfactoria para mí aparte de ser un descuido. Si alguien sabe algo, háganoslo saber! –

+0

Si necesita compatibilidad con enclavamiento para booleano puede usar mi implementación [InterlockedBoolean.cs] (https://gist.github.com/hanswolff/7926751) – quadfinity

Respuesta

47

Sí, hay una buena razón. La implementación de los métodos Interlocked requiere soporte de bajo nivel en el nivel del procesador. Ver this answer por ejemplo. Ese es un problema cuando defines un marco que es independiente de la arquitectura.

Implementar las técnicas de bloqueo bajo admitidas por la clase Interbloqueada en tipos de datos que son una fracción del tamaño de la palabra del procesador nativo es difícil. El enfoque RISC para el diseño de la CPU que era popular hace más de 10 años lo desalentó fuertemente. La falta de correspondencia entre el tamaño del operando y el ancho del bus de memoria nativo hace que sea muy difícil de implementar. Una razón por la cual la arquitectura x86 de Intel aún está en su regazo, sobreviviendo 30 años ya sin tomar los atajos. Más información de fondo sobre RISC en este wikipedia article.

+14

IOW, 'InterlockedExchange' no existe para NINGÚN tipo más pequeño que 32- bits, y la falta de una sobrecarga de 'bool' es solo una consecuencia de esto. –

+0

No hay instrucción CAS que opere en menos de 4 bytes, por lo que la sobrecarga Interbloqueado.Exchange que funcionó en un bool (1 byte) sería imposible de implementar de una manera que tuviera el mismo costo que las otras sobrecargas. Sospecho que los diseñadores del marco quieren evitar la confusión que resultaría. –

+0

.NET Boolean es una variable subyacente de 32 bits. La operación de enclavamiento en él puede usar la misma instrucción de CPU que uno para Int32. – Dennis

8

No responde la pregunta, pero como solución alternativa puede usar int en lugar de bool como lo hace C.

int m_IsFirstTime = 1; // 1 means true 0 means false. 

    void SomeMethod() 
    { 
     if (1 == Interlocked.Exchange(ref m_IsFirstTime , 0)) 
      // Do something for the first time. 

     else 
      // Do something for all other times. 

    } 

P.S. Si hay evidencia de que leer es más rápido que escribir, Interlocked.CompareExchange podría ser mejor para este caso (solo una primera vez y supongo que muchas no).

Cuestiones relacionadas