Tengo un problema muy extraño con las variables locales que están fuera de contexto en el depurador de Visual Studio 2010 para una aplicación de consola C# que se dirige a .NET 4.0. He buscado otras preguntas similares en SO, pero aunque algunas tienen los mismos síntomas, ninguna parece aplicarse directamente a este problema (todas parecen tener otras causas raíz).Variables fuera de contexto en Visual Studio 2010 Debugger
El problema es que para algunas variables (pero no todas) no recibo una información sobre herramientas con su valor, no aparecen en la ventana Locales, y obtengo "El nombre 'xyz' no existe en la corriente contexto "si los agrego a la ventana de observación. Parece afectar algunas variables pero no otras, y no puedo descifrar un patrón (no parece estar basado en miembro vs. local, clase vs. estructura, o cualquier otro diferenciador). He reiniciado mi computadora y Visual Studio, verificado que tengo una compilación limpia de depuración, me aseguré de que el marco de depuración sea correcto, me aseguré de actualizar las variables en la pantalla del reloj e intenté varios hechizos y conjuros.
He incluido una captura de pantalla a continuación (versión más grande en http://i.stack.imgur.com/JTFBT.png).
¿Alguna idea?
EDIT:
Agregando un poco de información adicional:
El problema es repetible. Las mismas variables exactas funcionan o no funcionan, incluso después de apagar completamente y reiniciar Visual Studio. Esto me lleva a creer que en realidad algo sistemático va mal en lugar de solo corrupción de memoria o algo así.
También descubrí que parece estar relacionado con el bloque try-catch. Si ubico el punto de interrupción fuera de la declaración try, puedo ver cualquiera de las variables dentro del alcance normalmente. Tan pronto como el punto de ejecución entre en la instrucción try, todas las variables fuera del bloque try se vuelven inaccesibles y solo puedo acceder a las que están dentro de la instrucción try. Es casi como si el depurador estuviera tratando el bloque try como un método separado (aunque puede ver que el código/compilador todavía tiene acceso a las variables dentro del alcance). ¿Alguien ha visto este comportamiento antes?
otra edición:
I (parcial) Retiro lo que dije sobre el try-catch ser sospechoso - parece que en esta parte del código de los objetos expuestos depurador esta extraña toma cosas fuera de contexto para cualquier encerramiento bloquear. Por ejemplo, si configuro un punto de interrupción directamente dentro de la declaración foreach en la captura de pantalla, puedo ver el valor de la variable "port" en cada iteración, pero ninguna de las variables fuera de la declaración foreach (que desaparecen tan pronto como ingreso al bloque foreach) . Luego, tan pronto como ingrese al bloque try, la variable "port" desaparecerá de repente. Esto se está poniendo realmente extraño.
Además, como se solicita, el código para todo el método está a continuación.
private void ConfigureAnnouncerSockets(XDocument configDocument)
{
XElement socketsElement = configDocument.XPathSelectElement("/Configuration/Network/AnnouncerSockets");
bool useDefault = true;
if (socketsElement != null)
{
//Use the default announcers? (they will be added at the end)
XAttribute defaultAttribute = socketsElement.Attribute("useDefault");
if (defaultAttribute != null)
{
useDefault = Convert.ToBoolean(defaultAttribute);
}
//Get the default frequency
int defaultFrequency = Announcer.DefaultFrequency;
XAttribute frequencyAttribute = socketsElement.Attribute("frequency");
if (frequencyAttribute != null)
{
defaultFrequency = Convert.ToInt32(frequencyAttribute.Value);
}
//Get all sockets
foreach (XElement socketElement in socketsElement.XPathSelectElements("./Socket"))
{
//Get the address
IPAddress address = IPAddress.Broadcast;
string addressAttribute = (string)socketElement.Attribute("address");
if(!GetAddress(addressAttribute, ref address, true))
{
Intelliplex.Log.Warn("Invalid announcer socket address: " + addressAttribute);
continue;
}
//Get the local address
IPAddress localAddress = null;
string localAddressAttribute = (string)socketElement.Attribute("localAddress");
if(!GetAddress(localAddressAttribute, ref localAddress, false))
{
Intelliplex.Log.Warn("Invalid announcer socket local address: " + localAddressAttribute);
continue;
}
//Get the port(s)
List<int> ports = new List<int>();
string[] ranges = ((string)socketElement.Attribute("port")).Split(new[] { ',' });
foreach (string range in ranges)
{
string[] portPair = range.Split(new[] { '-' });
int firstPort = Convert.ToInt32(portPair[0]);
int lastPort = portPair.Length > 1 ? Convert.ToInt32(portPair[1]) : firstPort;
do
{
ports.Add(firstPort);
} while (++firstPort <= lastPort);
}
//Get the local port
int localPort = socketElement.Attribute("localPort") != null
? Convert.ToInt32((string)socketElement.Attribute("localPort")) : 0;
//Get the frequency
int frequency = socketElement.Attribute("frequency") != null
? Convert.ToInt32((string)socketElement.Attribute("frequency")) : defaultFrequency;
//Create the socket(s) and add it/them to the manager
foreach (int port in ports)
{
try
{
IPEndPoint endPoint = new IPEndPoint(address, port);
IPEndPoint localEndPoint = localAddress == null
? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(localAddress, localPort);
Announcer socket = new Announcer(frequency, endPoint, localEndPoint);
AnnouncerSockets.Add(socket);
}
catch (Exception ex)
{
Intelliplex.Log.Warn("Could not add announcer socket: " + ex.Message);
}
}
}
}
//Add default announcement sockets?
if (useDefault)
{
ConfigureDefaultAnnouncerSockets();
}
}
+1 para círculos a mano alzada – James
Compruebe las propiedades de su proyecto: ¿está seguro de que la configuración de depuración no se ha modificado para "optimizar el código"? – phoog
@phoog Gracias por la sugerencia. Acabo de comprobar las propiedades del proyecto y "Deshabilitar código" está desmarcado. – daveaglick