对于面向.NET 4.0的C#控制台应用程序,Visual Studio 2010调试器中的局部变量脱离了上下文,我遇到了一个非常奇怪的问题。我在SO上搜索过其他类似的问题,但有些问题有相同的症状,似乎没有一个直接适用于这个问题(它们似乎都有其他根本原因)。
问题在于,对于某些变量(但不是全部),我没有得到带有值的工具提示,它们没有出现在Locals窗口中,我得到“当前上下文中不存在名称'xyz' “如果我将它们添加到Watch窗口。它似乎影响了一些变量而不影响其他变量,我无法弄清楚一个模式(它似乎不是基于成员与本地,类与结构或任何其他区别)。我已经重新启动了我的计算机和Visual Studio,验证了我是一个干净的Debug版本,确保调试框架是正确的,确保刷新监视屏幕中的变量,并尝试各种法术和咒语。
我在下面添加了一个屏幕截图(http://i.stack.imgur.com/JTFBT.png处的更大版本)。
有什么想法吗?
编辑:
添加一些其他信息:
问题是可重复的。即使在完全关闭并重新启动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();
}
}
答案 0 :(得分:9)
事实证明这与PostSharp中的错误有关。我一直在使用PostSharp,但从我的代码中删除了所有方面,并确保没有应用。我还用Reflector验证了方法在装配中是完整的。但是,它似乎只是引用PostSharp触发某种导致此问题的调试符号的操作。可以在这里找到(小)更多信息:
http://www.sharpcrafters.com/forum/Topic5794-21-1.aspx#bm7927
此外,在最新的PostSharp修补程序的发行说明中,修补程序2.1.5.6中的一个已修复问题是“调试符号:隐式迭代器中丢失的局部变量符号。”
当我安装最新最好的PostSharp时,问题消失了,宇宙恢复正常。希望这个问题/答案将帮助其他任何使用PostSharp的人在下一次官方PostSharp发布之前偶然发现这种奇怪的行为。确保你使用的是修补程序2.1.5.6或更高版本(鉴于错误的严重性,这可能应该是一个实际版本)。
感谢所有人的帮助。