У меня очень странная проблема с локальными переменными, находящимися вне контекста в отладчике Visual Studio 2010 для консольного приложения C #, предназначенного для .NET 4.0. Я искал другие похожие вопросы по SO, но, хотя некоторые из них имеют те же симптомы, ни один из них, похоже, не имеет прямого отношения к этой проблеме (кажется, что все они имеют другие коренные причины).
Проблема в том, что для некоторых переменных (но не всех) я не получаю всплывающую подсказку с их значением, они не отображаются в окне Locals, и я получаю "Имя xyz" не существует в текущем контексте «если я добавлю их в окно просмотра. Похоже, что он влияет на некоторые переменные, но не на другие, и я не могу понять шаблон (кажется, что он не основан на члене по сравнению с локальным, классом против структуры или любым другим дифференциатором). Я перезапустил свой компьютер и Visual Studio, подтвердил, что я нахожусь в чистой отладочной сборке, убедился, что кадр отладки правильный, удостоверился, что обновлялись переменные на экране наблюдения, и попытался использовать различные заклинания и заклинания.
Я включил скриншот ниже (увеличенная версия на 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();
}
}