nacho10f
nacho10f

Reputation: 5886

Linq in monotouch (debugging on device)

I am trying to run a Windows Azure Mobile Services query (using xamarins monotouch fork of the SDK).

This code runs fine on the Simulator but it blows up on the device:

this.table.Where (a => a.Sequence == sequence).Where (a => a.Week == week).ToListAsync()
                .ContinueWith (t =>
            {
                this.items = t.Result;
                this.tableView.ReloadData ();
                IsUpdating = false;
            }, scheduler);

The error I get is:

Exception has been thrown by the target of an invocation. ---> System.Exception: Attempting to JIT compile method 'System.Linq.jvm.Runner:GetDelegate ()' while running with --aot-only.

The only thing I´ve managed to do to make it work is removing the where conditions. This works just fine except I (obviously) dont get the results filtered as needed.

How should I rewrite my code to make it work on an actual iOS device?

UPDATE: table is a class variable of type *IMobileServiceTable < Activity > *

week and sequence are both of type int.

Activity is a POCO class.

    public class Activity
{
        public int ID {
            get;
            set;
        }
        public string Name {
            get;
            set;
        }

        public int CaloricRequirementMin {
            get;
            set;
        }

        public int CaloricRequirementMax {
            get;
            set;
        }

        public string Difficulty {
            get;
            set;
        }

        public int PlanId {get;set;}

        public string Type {
            get;
            set;
        }

        public int Sequence {
            get;
            set;
        }
        public int Week {
            get;
            set;
        }

        public int SubscriptionActivityId {
            get;
            set;
        }
}

I have double checked to make sure that these are both populated.

It words flawlessly on simulator.

Upvotes: 2

Views: 385

Answers (2)

nacho10f
nacho10f

Reputation: 5886

In the end I had to modify my code to use ReadAsync with a string query instead of the linq expressions.

this.table.ReadAsync(query)
                .ContinueWith (t =>
            {
                    items = (from item in t.Result.GetArray()
                             let act = item.GetObject()
                    select new Activity{
                        ID= Convert.ToInt32(act.GetNamedNumber("id")),
                        Name= act.GetNamedString("Name"),
                        SubscriptionActivityId = act.ContainsKey("SubscriptionActivityId") ? Convert.ToInt32(act.GetNamedNumber("SubscriptionActivityId")) : 0
                    }).ToList();


                    this.tableView.ReloadData ();
                IsUpdating = false;
            }, scheduler);

Upvotes: 1

Terry Westley
Terry Westley

Reputation: 126

The whole point of the MonoTouch Ahead Of Time (AOT) compiler is to avoid the problem that Apple does not allow compiling in iOS. It's one of several security policies, along with signed executables, app review, sandbox, and others. Unfortunately, certain LINQ expressions require JIT compiling and so cannot be run on device.

All LINQ expressions can be converted to non-LINQ, typically iterative, code. You could consider some LINQ alternatives that might work such as an Any() expression before you convert to iteration.

Upvotes: 1

Related Questions