2009-12-01 11 views

Respuesta

10

Michał Piaskowski desencadena la siguiente explicación:

La semántica de i-- en C# son para devolver el valor actual de i (es decir, el valor antes de la disminución se produce) y luego decremento i por uno.

Por lo tanto, tenemos que convertir eso a VB. No podemos usar i -= 1 porque esto no devuelve el valor actual de i antes de la disminución. Por lo tanto, necesitamos una operación que va a disminuir i pero devolver el valor de i antes de la reducción, algo así como:

Function DoPostDecrement(ByRef i As Integer) As Integer 
    i -= 1 
    Return i + 1 
End Function 

Pero esto sugiere utilizar el siguiente para evitar tener que escribir un método para llevar a cabo lo anterior:

System.Math.Max(
    someValueThatIsEqualToiMinusOne, 
    someValueThatIsEqualtoiBeforeTheDecrement 
) 

Pero VB.NET no le permitirá utilizar i -= 1 o i = i - 1 en lugar de someValueThatIsEqualToiMinusOne. Sin embargo, System.Threading.Interlocked.Decrement(i) es legítimo e igual al valor de i - 1. Una vez hecho esto, ya que los parámetros se evalúan de izquierda a derecha, someValueThatIsEqualtoiBeforeTheDecrement debería ser i + 1 (en ese momento el decremento se ha realizado para i + 1 es el valor de decremento previo.

Tenga en cuenta que el método anterior DoPostDecrement y el constructo System.Math.Max, System.Threading.Interlocked.Decrement podía tienen semánticas diferentes en un contexto multiproceso.

+1

i = i - 1; no es lo mismo que yo--; esto soy yo; –

+0

Bueno, eso efectivamente lo explica en ese momento. Ver mi edición – jason

+1

@Downvoter: explíquese. – jason

0

La única razón que puedo ver es a partir

Interlocked.Decrement Method

Decre menciona una variable especificada y almacena el resultado, como operación atómica .

2

La operación Interlocked es atomic; en contextos multiproceso, puede usarlo sin tener que bloquearlo, si tiene cuidado.

+2

Es cierto, pero no creo que es por eso que se ha utilizado. Se acaba de utilizar como una forma conveniente de convertir el operador en VB.Net. El operador C# --- no es atómico: y tampoco creo que el fragmento del código traducido sea atómico (¿qué ocurre si otro hilo modifica i entre Decremento y la evaluación de i + 1)? – MarkJ

0

Depende - es "i" una variable compartida? ¿Está en un entorno seguro para subprocesos?

Si "i" es un número entero, entonces i-- hace esencialmente lo siguiente (ignorando los detalles):

  1. resta uno de i
  2. asigna ese valor de nuevo a i

Como puede ver, hay> 1 pasos.Si "i" está en una ubicación no segura para subprocesos (variable estática compartida entre subprocesos, etc.), entonces el subproceso podría detenerse en medio de esos dos pasos, otro subproceso podría ejecutar ambos pasos, y luego tendría un problema con datos no válidos.

La clase Interlocked esencialmente combina los dos pasos anteriores en un solo paso, proporcionando una operación atómica. Ahora no tiene que preocuparse por los hilos, ya que es una operación única y no puede ser interrumpida por otro hilo.

+1

En otro comentario: "Yo diría que no debería, ya que podría cambiar la semántica en un contexto multiproceso". En un contexto de subproceso único, el comportamiento no se modifica. En un contexto de subprocesos múltiples, ahora se garantiza que el comportamiento hará algo predecible, que no sería antes. De todas formas, este es un "buen cambio". – jvenema

+0

Cierto, pero no creo que ese sea el motivo por el cual se ha utilizado Increment. Se acaba de utilizar como una forma conveniente de convertir el operador en VB.Net. El operador C# '--' no es atómico: y tampoco creo que el fragmento del código traducido sea atómico. ¿Qué ocurre si otro hilo modifica' i' entre Decrement y la evaluación de 'i + 1'? http://msdn.microsoft.com/en-us/library/aa446528.aspx – MarkJ

+0

Buen punto Marcar ... de alguna manera he pasado por alto el hecho de que el i + 1 está ahí :) Estoy seguro de que tienes razón , es solo una cosa de conversión. – jvenema

0

Para responder a su pregunta, este aspecto de converter.telerik.com es demasiado conservador para los problemas de subprocesamiento. WAAAY excesivamente conservador. Revertiría el código a i-- si la misma instancia de i no está siendo mutada de varios subprocesos al mismo tiempo.

+0

¿Puede el votante inferior aclararme con un comentario? –

+0

Creo que Decrement acaba de usarse como una forma conveniente de convertir el operador '--' en VB.Net. No hay un operador '-' en VB.Net así que no puedes "revertir el código" a 'i -' a menos que lo reviertes a C# – MarkJ

+0

Ahh ya veo. ¡Gracias por aclarar eso! –

Cuestiones relacionadas