如何避免.NET CF 3.5和CE 6 R3中出现严重错误

时间:2013-05-03 10:18:32

标签: c# .net compact-framework windows-ce

当我在带有附加调试器的设备上启动此示例程序时,会发生严重错误。

这是我们真实应用程序中发生的事情的简化版本。

我发现的是:

  • 必须附加调试器
  • 必须以某种方式填充内存(我认为这会强制垃圾收集)
  • 垃圾(位图)对象必须存在。其他对象可能会导致相同的错误
  • 必须显示表单(如果使用Application.Run()或ShowDialog则没有区别)

然后,当表单可见且GC收集位图时,会发生严重错误。

我正在使用.NET Compact Framework 3.5运行WindowsCE 6 R3。

static class Program {

    static void Main() {
        // Fill up memory - Depends on device
        var memory = new int[100000 * 150];

        // Settings the priority higher will raise the error earlier.
        // With Priority set to Normal the EXE won't get freed correct.
        // Without this line i have to reboot the CE after every test run...
        Thread.CurrentThread.Priority = ThreadPriority.Highest;

        // 80 is just random choosen. The error occurs also with 30 Bitmaps...
        for (int o = 1; o < 80; o++) {
            // Create a Bitmap and don't free it manually. The
            // The garbage collector will take care of it :)
            var bitmap = new Bitmap(100, 100);

            // When i dispose the Bitmap, everything works fine...
            //bitmap.Dispose();
        }

        // Force a GC run
        System.Diagnostics.Debug.WriteLine(GC.GetTotalMemory(true));

        // Then error occurs when the form is shown.
        System.Windows.Forms.Application.Run(new System.Windows.Forms.Form());
    }
}

我已经找到了类似的问题,但没有回答......

到目前为止我尝试了什么:

  • 手动清理所有资源。我已经搜索了所有位图创建并处理或缓存它们。错误仍然存​​在,不仅是Bitmaps不好......

2 个答案:

答案 0 :(得分:1)

我有一个理论,那就是系统交换。如果调试器试图检索自己大小超过CE's paging pool大小的变量的内容,我可以想象这会死锁。调试器停止系统读取数据,但系统无法提供内容,因为它无法交换数据。使用IOCTL_HAL_GET_POOL_PARAMETERS,您应该能够检测系统是否正在交换。

答案 1 :(得分:0)

这很难为此找到答案。

当你说a serious error occurs时,我的猜测是你看到OutOfMemoryException

The Garbage Collector(GC)在框架分配给GC或调用它时运行。

如果您创建/使用内存的速度比Framework能够调用GC的速度快,则可能会耗尽内存 - 尤其是在CF应用程序中。

上面的MSDN链接说明如下:

  

.NET Framework的垃圾收集器管理应用程序的内存分配和释放。每次使用new运算符创建对象时,运行时都会从托管堆中为对象分配内存。只要托管堆中的地址空间可用,运行时就会继续为新对象分配空间。但是,记忆并不是无限的。最终垃圾收集器必须执行一个集合才能释放一些内存。垃圾收集器的优化引擎根据正在进行的分配确定执行收集的最佳时间。当垃圾收集器执行集合时,它会检查托管堆中不再被应用程序使用的对象,并执行必要的操作来回收它们的内存。

要解决这个问题,您需要在完成资源后释放资源。如果您稍后需要该数据,可以将资源保存到某种介质(闪存数据,硬盘驱动器等)以便以后检索。

有关此内容的更多信息,请阅读Steven Pratschner的博客,标题为An Overview of the .Net Compact Framework Garbage Collector