У меня возникает очень странная проблема с локальными переменными, которые не соответствуют контексту в отладчике Visual Studio 2010 для консольного приложения С#, ориентированного на .NET 4.0. Я искал другие подобные вопросы на SO, но, хотя некоторые из них имеют одинаковые симптомы, ни один из них не применяется непосредственно к этой проблеме (все они имеют другие причины).
Проблема в том, что для некоторых переменных (но не для всех) я не получаю всплывающую подсказку с их значением, они не отображаются в окне Locals, и я получаю: "Имя" xyz "не существует в текущем контексте" если я добавлю их в окно "Смотреть". Похоже, что это влияет на некоторые переменные, но не на другие, и я не могу понять шаблон (он, похоже, не основан на члене или локальном, классе или структуре или любом другом дифференциаторе). Я перезапустил свой компьютер и Visual Studio, подтвердил, что у меня чистая сборка Debug, убедитесь, что фрейм отладки верен, убедитесь, что обновили переменные на экране часов, и попытались выполнить различные заклинания и заклинания.
Я включил скриншот ниже (большая версия на http://i.stack.imgur.com/JTFBT.png).
Любые мысли?
EDIT:
Добавление дополнительной информации:
Проблема повторяема. Точно такие же переменные работают или не работают даже после полного завершения и перезапуска Visual Studio. Это заставляет меня думать, что на самом деле происходит что-то систематическое, а не просто повреждение памяти или что-то в этом роде.
Я также обнаружил, что он, похоже, связан с блоком try-catch. Если я помещаю точку останова вне оператора try, я могу увидеть любую из переменных в области видимости. Как только точка выполнения входит в оператор try, все переменные за пределами блока try становятся недоступными, и я могу получить доступ только к тем, которые содержатся в инструкции try. Это почти так, как если бы отладчик обрабатывал блок try как отдельный метод (хотя вы можете видеть, что код/компилятор все еще имеет доступ к переменным в области видимости). Кто-нибудь видел это поведение раньше?
ДРУГОЙ РЕДАКТИРОВАНИЕ:
Я (частично) вернул то, что я сказал о подозреваемом try-catch, - похоже, что в этой части кода отладчик демонстрирует этот нечетный прием материала вне контекста для любого закрывающего блока. Например, если я устанавливаю точку останова непосредственно внутри оператора foreach на скриншоте, я могу увидеть значение переменной "port" на каждой итерации, но ни одна из переменных вне оператора foreach (которые исчезают, как только я вхожу в блок foreach), Затем, как только вы входите в блок try, переменная "port" внезапно исчезает. Это становится действительно странным.
Кроме того, в соответствии с запросом, код для всего метода ниже.
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();
}
}