我正在研究在WindowsCE 6.0上运行.NETCF 3.5的C#代码,它为Func`2<>抛出MissingMethodExceptions在运行时。发生异常的代码部分是随机的。
奇怪的是,这种情况发生在你已经使用了一段时间的应用程序时,肯定已经发生了很多对Func`2的调用。 (例如,通过IEnumerable.Select()或.Where()) 如果你只是在应用程序的生命周期中加载足够的类型,使得程序集文件大小的总和超过~18MB,似乎这种行为就开始了。但是设备上有足够的内存(RAM)来加载Type。
同时激活LoaderLogging但无济于事。它只显示Func`2的TypeLoad错误。
当我没有想法时: 造成这种错误的原因是什么?
不幸的是,我不能共享任何代码,因为它是1)我工作的公司的财产和2)许多一万行代码。
答案 0 :(得分:4)
似乎.NETCF存在限制:
每个泛型类型声明只能构造1024个唯一的封闭类型。(有关详细信息,请参阅“限制”部分:http://blogs.msdn.com/b/romanbat/archive/2005/01/06/348114.aspx)
含义:
List<int> a;
List<int> b;
List<int> c;
需要一个“插槽”,
List<int> d;
List<string> e;
需要两个“插槽”(两个独特的关闭),依此类推。
棘手的是:通常这会引发ArgumentException,但有时.NETCF会抛出MissingMethodExceptions。 (参见“3.抛出异常的差异。”:http://blogs.msdn.com/b/nazimms/archive/2005/01/25/360324.aspx)
我们尽可能使用自己的委托类型减少了Func`2的使用,这解决了这个问题。
答案 1 :(得分:0)
如果您了解Windows CE内存管理的背景,那么您已经自己回答了问题: “...使得汇编文件大小的总和超过~18MB。但是设备上有足够的内存(RAM)来加载Type ....”
你知道,每个进程只获得一个32MB的程序内存插槽,无论是否有GB RAM或更多!那是设计上的。 您知道,您或任何其他正在运行的进程加载的DLL被加载到每个进程的32MB插槽中(尽管Windows Embedded Handheld 6.5没有加载完整大小)。因此,加载的DLL越多,进程就会获得更少的可用程序内存。有关详细信息,另请参阅http://community.intermec.com/t5/General-Development-Developer/Slaying-the-virtual-memory-monster/m-p/16764。
如果从32MB插槽底部增长的进程内存增加了从32MB插槽顶部加载的加载DLL,您将获得奇怪的程序行为甚至崩溃。
以上内容适用于所有基于Windows CE 5的操作系统版本,如Windows Mobile 6.1,Windows Mobile 5甚至最新的Windows Mobile 6.5.3(嵌入式手持设备)。 以上内容必须针对基于Windows CE 6的操作系统版本进行修订。
问候
约瑟夫