Monotouch blows up on LINQ query when using device

2019-04-12 03:57发布

问题:

Here's the error I get:

| mscorlib | | Attempting to JIT compile method 'System.Linq.OrderedEnumerable`1:GetEnumerator ()' while running with --aot-only.

From what I've read it looks like the compiler doesn't include a method in this case "GetEnumerator", that the code needs because of LINQ. What is the correct course of action for making sure the compiler includes it?

Pretty much everyone that runs into this that I've found online just gets rid of the linq query and moves on with life but I am tired of re-writing my code when something like this pops up. Also I'm not sure exactly which linq query is causing the issue and I'm slowly going through my code and re-writing all the linq queries until I find it.

回答1:

The GetEnumerator method is not really missing - but it was not AOT-ed before getting into the device. So the JIT is trying to compile it on the device. Now due to Apple restriction MonoTouch (or anything else) cannot JIT code on devices (but that will work on the simulator where no such restriction exists).

So what's the real error: it's that (generic) type hat the AOT compiler could not predict (and compile code for it).

A trick to find your issue (easier than re-writing every LINQ code you have) is to compile your C# code and then ildasm the assembly. Next find in which method(s) OrderedEnumerable`1 is being used (LINQ can hide things very easily).

Once found you might need to rewrite that part but, in some cases, you can "help" the AOT compiler by making it more obvious that the type (represented by `1) will be needed.



回答2:

Does number #17 help you in this link?

http://ios.xamarin.com/Documentation/Troubleshoot

"System.ExecutionEngineException: Attempting to JIT compile method (wrapper managed-to-managed) Foo[]:System.Collections.Generic.ICollection`1.get_Count()"

You may well need to "hack" a workaround to fix this, sadly - but it is fixable. Can you please update your question with the actual LINQ query?



回答3:

Found the offending line of code:

// currentDates is a List<DateTime>
return (from dt in currentDates orderby dt.Date ascending select dt).ToList();

I changed it to use

CurrentDates.Sort()

and that avoided calling the GetEnumerator that wasn't getting AOT-ed. No longer blows up.