Noté que en System.Threading.TimerBase.Dispose()
el método hay un try{} finally{}
bloque pero try{}
está vacío.
¿Hay algún valor en usar try{} finally{}
con un vacío try
?
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Dispose(WaitHandle notifyObject)
{
bool status = false;
bool bLockTaken = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
}
finally {
do {
if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) {
bLockTaken = true;
try {
status = DeleteTimerNative(notifyObject.SafeWaitHandle);
}
finally {
m_lock = 0;
}
}
Thread.SpinWait(1);
// yield to processor
}
while (!bLockTaken);
GC.SuppressFinalize(this);
}
return status;
}
Respuestas:
De http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/ :
fuente
Thread.BeginCriticalRegion()
no evita que un hilo sea abortado, más bien le dice al tiempo de ejecución que si un hilo es abortado, entonces el estado global está corrupto, y todo el dominio de la aplicación está a punto de matar.BeginCriticalSection()
realmente no estaba allí en .NET 1.x, pero no hay causa y efecto, lo que implica decir porque . De hecho, en .NET 1.x, incluso unfinally
bloque podría haber sido interrumpido por un aborto de subprocesos. Estos mecanismos tienen un propósito diferente: hacer el trabajo en unfinally
previene abortar a mitad de camino en el código, mientras queBeginCriticalSection()
solo declara en el tiempo de ejecución que el estado global está en riesgo.Esto es para evitar
Thread.Abort
interrumpir un proceso. La documentación para este método dice que:Esto se debe a que para recuperarse con éxito de un error, su código deberá limpiarse después de sí mismo. Dado que C # no tiene destructores de estilo C ++,
finally
y losusing
bloques son la única forma confiable de garantizar que dicha limpieza se realice de manera confiable. Recuerde que elusing
bloque se convierte en esto por el compilador:En .NET 1.x, existía la posibilidad de que el
finally
bloque se abortara. Este comportamiento se cambió en .NET 2.0.Además,
try
el compilador nunca optimiza los bloques vacíos .fuente
Dispose(false);
. docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…