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