2009-01-08 16 views

Respuesta

39

No está haciendo nada mal. De acuerdo con la documentation:

Un campo volátil no debe normalmente ser transmitida usando un ref o fuera parámetro, ya que no será tratado como volátil dentro del alcance de la función. Existen excepciones a esto, como cuando se llama a una API entrelazada .

+18

Diría que los métodos de Enclavamiento aún no lo tratan de manera diferente a como tratarían a cualquier otro campo, es solo que los campos * todos * se manejan de manera especial por Enclavamiento. –

+3

De acuerdo. Volátil es irrelevante para la API enclavada. Pero en ciertos casos, es muy útil mezclar Enclavamiento y volátil. – IamIC

+0

un poco tarde para la fiesta, pero @IamIC: ¿me importa elaborar qué casos serían? – jajdoo

3

Aparecerá el error porque está pasando el campo por referencia. Creo que lo que esto significa es que el método de destino no tiene idea de que el campo está marcado como volatile, y por lo tanto no lo tratará como tal.

30

Básicamente, la advertencia es que cuando pasa un campo volátil por referencia, el código de llamada no sabe tratarlo de manera volátil. Para enclavamiento.Incremento que probablemente no importe, debido a la naturaleza del método, pero no es necesario que la variable sea volátil de todos modos si está utilizando Enclavamiento.

En general, creo que me gustaría evitar la mezcla de los dos - Si está utilizando Interlocked, hacerlo en todas partes (usando Interlocked.CompareExchange(ref counter, 0, 0) para leerlo). No puedo decir que utilizo volátiles muy a menudo, personalmente. Para los contadores simples I puede usar Enclavamiento, pero es más probable que use un candado para la mayoría de las tareas.

+0

Usted está recibiendo me confunde. En una pregunta anterior (395232) entendí por su respuesta que necesitaba tanto enclavamiento como volátil. Ahora dices "no necesitas que la variable sea volátil de todas formas si estás usando Enclavamiento". –

+0

No, son alternativas entre sí: "O preferiblemente use Enclavamiento, una variable volátil o un candado". Eso estaba destinado a dar tres enfoques * diferentes *, no uno combinado. ¿Esa era la parte que te estaba engañando? –

+0

Entiendo que en un entorno de multiprocesador, las memorias caché múltiples pueden hacer que un procesador incremente un valor en caché que no sea el último valor. En ese caso, hasta donde yo sé, un enclavamiento no ayudará, porque no crea el MemoryBarrier que se necesita para actualizar los cachés. –

26

Utilice esta:

 #pragma warning disable 420 
     //      M 
     //      dM 
     //      MMr 
     //      4MMML     . 
     //      MMMMM.    xf 
     //  .    "MMMMM    .MM- 
     //  Mh..   +MMMMMM   .MMMM 
     //  .MMM.   .MMMMML.   MMMMMh 
     //  )MMMh.  MMMMMM   MMMMMMM 
     //  3MMMMx.  'MMMMMMf  xnMMMMMM" 
     //  '*MMMMM  MMMMMM.  nMMMMMMP" 
     //   *MMMMMx "MMMMM\ .MMMMMMM= 
     //   *MMMMMh "MMMMM" JMMMMMMP 
     //    MMMMMM 3MMMM. dMMMMMM   . 
     //    MMMMMM "MMMM .MMMMM(  .nnMP" 
     // =..   *MMMMx MMM" dMMMM" .nnMMMMM* 
     // "MMn...  'MMMMr 'MM MMM" .nMMMMMMM*" 
     //  "4MMMMnn.. *MMM MM MMP" .dMMMMMMM"" 
     //  ^MMMMMMMMx. *ML "M .M* .MMMMMM**" 
     //   *PMMMMMMhn. *x > M .MMMM**"" 
     //    ""**MMMMhx/.h/ .=*" 
     //      .3P"%.... 
     //     nP"  "*MMnx 
     if(Interlocked.CompareExchange(ref isLoaded, 1, 0) != 0) 
      return; 
     #pragma warning restore 420 
+10

ilustraciones bonitas de ASCII, pero no responde a la pregunta –

+3

Pero sí es útil una vez que comprende las otras respuestas, en caso de que decida usar tanto enclavadas como volátiles. – yoyo

+2

@JaderDias - No, pero te dice qué hacer con la advertencia. Lo cual es súper útil. - También la obra de arte también fue divertida. – BrainSlugs83

Cuestiones relacionadas