遇到OutOfMemoryException异常会使调试变得困难。

3
当我调试程序并在立即窗口中尝试执行某些操作时,有时会在立即窗口中显示错误消息,内容为:“由于内存不足异常,函数评估已被禁用。”当将鼠标悬停在对象上查看其属性时,也会出现此错误消息。经过尝试找到问题的原因后,我将问题缩小到以下代码示例:
using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //outofmemoryexception can be thrown by Image.FromFile("path/that/does/not/exist.png")
                //if the path points to a file that is not an image
                throw new OutOfMemoryException();
            }
            catch (OutOfMemoryException ex)
            {
                //caught the exception
                //so no problem, right?
            }

            //Random object to use in immediate window
            Random rand = new Random();

            //Also, try hovering over this regex and take a look at its properties.
            var test = new Regex("");

            //put a breakpoint here (at the next closing curly brace) and try calling rand.Next() in the immediate window
        }
    }
}

似乎调试器在OutOfMemoryException发生时会发生问题,即使已经捕获该异常...
我可以想象没有人曾经考虑过能够调试一个遇到OutOfMemoryException的程序。但不幸的是,当文件不是图像时,Image.FromFile会抛出该错误...
问题如下:
1.以上代码示例是否给其他人带来了问题?
2.有人能解释一下吗?为什么会发生这种情况?
3.最后,我该怎么防止这种情况发生?

如果找不到文件,它应该抛出“FileNotFoundException”。如果“文件没有有效的图像格式”或“GDI+不支持文件的像素格式”,则会抛出OOME。http://msdn.microsoft.com/en-us/library/stf701f5(v=vs.110).aspx - Dave Zych
顺便说一下,我很高兴见到将这个错误与OOME关联起来的人。 - Patrice Gahide
2
调试器会停止尝试评估监视器,如果发生了非常严重的事情。为了确保不再发生这种情况。它不会在您继续调试器之前重置该状态。是的,相当遗憾的是,GDI+异常并不总是意味着您实际上已经OOM。尽管如此,那个调试会话已经完成了,您必须采取一些激烈的措施来修复它。 - Hans Passant
@Dave Zych:你说得对,我犯了一个错误,是当文件不是图像时。 - user886079
@Dave 是的,那就是我在之前评论中提供的链接。这又是一个证明 Stackoverflow 对于未访问链接的 CSS 需要改变的例子!我希望每个人都能致力于解决这个令人讨厌的问题! - Patrice Gahide
显示剩余2条评论
1个回答

0

是的,这是预期的行为。

您需要让调试器运行(跨过或在下一行上设置断点并单击F5),以使其从此状态恢复。即使有时它也没有帮助,运行直到您命中堆栈上更高的其他函数通常会使调试器再次合作。

请注意,OOM不是唯一的情况 - 即立即窗口中长时间运行的代码也会使调试器处于相同的状态。

更多信息 - MSDN 禁用函数评估..., SO - 由于先前的函数评估超时而禁用函数评估


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接