经过2周的开发后,我首先在iphone上尝试了我的应用程序,它在以下行崩溃(在模拟器中完美运行):
我有以下代码:
private readonly Dictionary<string, QueueItem queued = new Dictionary<string, QueueItem>();
private void Processqueue()
{
KeyValuePair<string, QueueItem> valuePair = queued.FirstOrDefault();
// Crashes with: System.TypeInitializationException has been thrown
// "And exception was thrown by the type initializer for PredicateOf`1"
}
private class QueueItem
{
public string Url { get; set; }
public Action<string> ImageLoaded { get; set; }
public bool Pending { get; set; }
}
希望有人知道该怎么做。
感谢
答案 0 :(得分:2)
不知何故,AOT编译器无法检测到这种情况,所以是的,您应该提交有关它的错误报告。与此同时,您可以通过以下方式解决此问题:
KeyValuePair<string, QueueItem> valuePair = queued.FirstOrDefault (delegate { return true; });
这将避免在执行完全相同的事情(执行明智)时达到PredicateOf并且比循环自己更短。
你也得到了一个TypeLoadException,因为原始异常发生在静态构造函数中(它总是导致TLE,内部异常应该是你期望看到的异常)。
更新:这是以bug #300提交并在最新版本的MonoTouch(4.2 +)中修复
答案 1 :(得分:0)
可能,因为静态编译器无法确定字典中对FirstOrDefault的调用是否需要编译PredicateOf。
答案 2 :(得分:0)
将静态构造函数和新的AOTHint()
静态方法添加到包含Processqueue()
方法的类中。在AOTHint()
中,创建一个您遇到问题的特定泛型类的新实例,并调用它遇到问题的方法。
static MyClass() {
AOTHint();
}
static void AOTHint()
{
// @fixes: ExecutionEngineException: Attempting to JIT compile method 'System.Collections.Generic.Dictionary`1.FirstOrDefault ()' while running with --aot-only.
(new Dictionary<string, QueueItem>()).FirstOrDefault();
}
注意:我没有尝试在MonoTouch中运行上面的特定代码;这是一个改编的解决方案,来自我之前曾经多次尝试过“尝试JIT编译方法”的问题。如果这不起作用,您可能需要使用AOTHint()
中指定和调用的类型。
对于每个有问题方法的类,针对每种问题类型执行此操作,并且从现在到Mono计算出如何使其通用编译减少错误时,您的担忧将会消失。
这可以确保AOT编译器确切地知道您需要什么,以极少的成本浪费地创建一些空的通用对象,并在应用程序启动时调用它们上的一些LINQ方法。