Ho un problema molto strano con le variabili locali che sono fuori dal contesto nel debugger di Visual Studio 2010 per un'applicazione console C# che utilizza .NET 4.0. Ho cercato altre domande simili su SO, ma mentre alcuni hanno gli stessi sintomi, nessuno sembra applicarsi direttamente a questo problema (tutti sembrano avere altre cause).Variabili fuori contesto in Visual Studio 2010 Debugger
Il problema è che per alcune variabili (ma non tutte) non ottengo un suggerimento con il loro valore, esse non compaiono nella finestra Locali e ottengo "Il nome 'xyz' non esiste nell'attuale contesto "se li aggiungo alla finestra di controllo. Sembra che influenzi alcune variabili ma non altre, e non riesco a capire un modello (non sembra essere basato su membro vs. locale, classe vs. struct o qualsiasi altro elemento di differenziazione). Ho riavviato il mio computer e Visual Studio, ho verificato che sono in una build debug pulita, mi sono assicurato che il frame di debug fosse corretto, mi sono assicurato di aggiornare le variabili nella schermata di controllo e ho tentato vari incantesimi e incantesimi.
Ho incluso uno screenshoot di seguito (versione più grande a http://i.stack.imgur.com/JTFBT.png).
Qualche idea?
EDIT:
Aggiunta di alcune informazioni aggiuntive:
Il problema è ripetibile. Le stesse variabili esatte funzionano o non funzionano, anche dopo aver completamente chiuso e riavviato Visual Studio. Questo mi porta a credere che ci sia in realtà qualcosa di sistematico che va storto piuttosto che solo la corruzione della memoria o qualcosa del genere.
Ho anche scoperto che sembra essere correlato al blocco try-catch. Se posizioni il punto di interruzione all'esterno dell'istruzione try, è possibile vedere normalmente qualsiasi variabile nell'ambito. Non appena il punto di esecuzione entra nella dichiarazione try tutte le variabili al di fuori del blocco try diventano inaccessibili e posso accedere solo a quelle contenute nell'istruzione try. È quasi come se il debugger trattasse il blocco try come metodo separato (sebbene si possa vedere che il codice/compilatore ha ancora accesso alle variabili in-scope). Qualcuno ha mai visto questo comportamento prima?
ALTRO EDIT:
I (parzialmente) riprendere quello che ho detto circa il try-catch essendo sospetto - sembra che in questa parte del codice mostre debugger questa presa di roba strana fuori contesto per qualsiasi racchiude bloccare. Ad esempio, se imposto un breakpoint direttamente all'interno dell'istruzione foreach nello screenshot, posso vedere il valore della variabile "port" su ogni iterazione, ma nessuna delle variabili al di fuori dell'istruzione foreach (che scompare non appena inserisco il blocco foreach) . Quindi, non appena si inserisce il blocco try, la variabile "port" scompare improvvisamente. Questo sta diventando davvero strano.
Inoltre, come richiesto, il codice per l'intero metodo è riportato di seguito.
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 per cerchi a mano libera – James
Verifica le proprietà del progetto: sei sicuro che la configurazione di debug non sia stata modificata in "codice di ottimizzazione"? – phoog
@phoog Grazie per il suggerimento. Ho appena controllato le proprietà del progetto e "Ottimizza codice" è deselezionato. – daveaglick