Словарь аварийного сбоя Monotouch FirstOrDefault () Тип Инициализатор PredicateOf - PullRequest
1 голос
/ 29 июня 2011

после 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; }
}

Надеюсь, что у кого-то есть идеи, что делать.

спасибо

Ответы [ 3 ]

2 голосов
/ 17 июля 2011

Каким-то образом AOT-компилятор не смог обнаружить этот случай, так что да, вам следует сообщить об ошибке.В то же время вы можете обойти это, выполнив:

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

, что позволит избежать достижения PredicateOf при выполнении точно такой же вещи (в плане исполнения) и немного короче, чем зацикливание себя.

Такжевы получили исключение TypeLoadException, поскольку исходное исключение произошло в статическом конструкторе (который всегда приводит к TLE, внутреннее исключение должно быть тем, которое вы ожидали увидеть).

ОБНОВЛЕНИЕ: Это былозарегистрировано как ошибка # 300 и исправлено в последних версиях MonoTouch (4.2 +)

0 голосов
/ 21 августа 2014

Добавьте статический конструктор и новый 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 во время запуска приложения.

0 голосов
/ 30 июня 2011

Вероятно, поскольку статический компилятор не смог определить, что вызов FirstOrDefault в словаре потребует компиляции PredicateOf.

...