En su article about preventing multiple instances de una aplicación, Michael Covington presenta este código:GC.KeepAlive frente a la utilización
static void Main() // args are OK here, of course
{
bool ok;
m = new System.Threading.Mutex(true, "YourNameHere", out ok);
if (! ok)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1()); // or whatever was there
GC.KeepAlive(m); // important!
}
Explica que la GC.KeepAlive (m) es necesario para evitar que el recolector de basura se acumule el mutex temprana , ya que no hay referencias adicionales al mismo.
Mi pregunta: ¿envolver el mutex en un uso hará lo mismo? Es decir, ¿lo siguiente también evitará que el GC tire de la alfombra debajo de mí?
static void Main() // args are OK here, of course
{
bool ok;
using (var m = new System.Threading.Mutex(true, "YourNameHere", out ok))
{
if (! ok)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1()); // or whatever was there
}
}
Mi reacción visceral es que el uso va a funcionar, ya que el uso está (se supone que) equivalente a:
Mutex m = new System.Threading.Mutex(true, "YourNameHere", out ok);
try
{
// do stuff here
}
finally
{
m.Close();
}
Y yo creo que la m.Close() no sería suficiente para indicarle al compilador JIT que hay otra referencia, evitando así la recolección prematura de basura.
No soy experto en CLR (por lo que no estoy agregando ninguna respuesta) pero me parece que lo que está haciendo debería funcionar. Yo digo, pruébalo y mira. –
Cuando hablamos del GC, "probarlo y verlo" resulta ser una mala idea. He tenido casos en los que las pruebas dicen que debería funcionar, pero fallaron en la producción. Mucho tiene que ver con la diferencia en la forma en que el compilador JIT funciona en modo Release vs. Debug. –