Monotouch 崩溃字典 FirstOrDefault() 类型初始化器 PredicateOf

发布于 2024-11-17 10:53:27 字数 652 浏览 1 评论 0原文

经过 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; }
}

希望有人知道该怎么做。

谢谢

after 2 Weeks of Developement i first tried my app on the iphone and it crashes at the following line (which works perfectly in the simulator):

i have the following code:

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; }
}

Hope that someone has an idea what to do.

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜点 2024-11-24 10:53:27

不知何故,AOT 编译器无法检测到这种情况,所以是的,您应该提交有关它的错误报告。同时,您可以通过执行以下操作来解决此问题:

KeyValuePair<string, QueueItem> valuePair = queued.FirstOrDefault (delegate { return true; });

这将避免在执行完全相同的操作(执行方面)时到达 PredicateOf,并且比自己循环要短一些。

此外,您还得到了 TypeLoadException,因为原始异常发生在静态构造函数中(这总是会导致 TLE,内部异常应该是您期望看到的异常)。

更新:这已归档为 bug #300 和已在最新版本的 MonoTouch (4.2+) 中修复

Somehow the AOT compiler could not detect this case so yes you should file a bug report about it. In the mean time you can workaround this by doing:

KeyValuePair<string, QueueItem> valuePair = queued.FirstOrDefault (delegate { return true; });

which will avoid reaching PredicateOf while doing the exact same thing (execution wise) and a bit shorter than looping yourself.

Also you got a TypeLoadException because the original exception occurred in a static constructor (which always results in a TLE, the inner exception should be the one you expected to see).

UPDATE: This was filed as bug #300 and fixed in recent releases of MonoTouch (4.2+)

定格我的天空 2024-11-24 10:53:27

可能是因为静态编译器无法确定对字典中 FirstOrDefault 的调用需要编译 PredicateOf。

Likely, because the static compiler could not determine that the call to FirstOrDefault in the dictionary will require the compilation of PredicateOf.

遮了一弯 2024-11-24 10:53:27

将静态构造函数和新的 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 方法。

Add a static constructor and a new AOTHint() static method to the class that contains the Processqueue() method.  In AOTHint(), create a fresh instance of the specific generic class you're having trouble with, and call the method it's having trouble with.

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();
}

Note: I haven't tried running your specific code with the above in MonoTouch; this is an adapted solution from what I've used a number of times before for “Attempting to JIT compile method” issues.  If this doesn't work, you'll likely need to play with the types specified and called in AOTHint().

Do this for each class that has problem methods, for each of the problem types, and your worries will be gone in the time between now and whenever the Mono figures out how to make their generic compilation less-buggy.

This works by making sure the AOT compiler knows exactly what you need, at the minimal cost of wastefully creating a handful empty generic objects and calling a handful of LINQ methods on them at app launch time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文