ios - IMobileServiceClient.PullAsync deadlock when trying to sync with Azure Mobile Services -


i have classes below.

public class azuremobiledatacontext : iasyncinitialization     {         private static readonly lazy<azuremobiledatacontext> lazy =             new lazy<azuremobiledatacontext> (() =>                  new azuremobiledatacontext(                     new mobileserviceclient(                                 "http://myservice.azure-mobile.net/",                                 "123456789abcdefghijklmnop")));          public static azuremobiledatacontext instance { { return lazy.value; } }         public task initialization { get; private set; }         public imobileserviceclient context { get; private set; }          private object lockobj = new object ();         private static mobileservicesqlitestore store;          public azuremobiledatacontext (imobileserviceclient context)         {             context = context;             initialization = init ();             initialization.continuewith (async (antecedent) => {                 await context.synccontext.initializeasync (store, new mobileservicesynchandler ());             });         }          private task init ()         {             return task.run (() => {                 lock (lockobj) {                     if (!context.synccontext.isinitialized) {                         try {                             store = new mobileservicesqlitestore ("mysqlite.db3");                              store.definetable<post> ();                             store.definetable<postphotourl> ();                             store.definetable<user> ();                             store.definetable<club> ();                             store.definetable<district> ();                         } catch (exception ex) {                             debug.writeline ("init: {0}", ex.message);                         }                     }                 }             });         }          public async task<imobileservicesynctable<tentity>> gettableasync<tentity> ()         {             await initialization;             return context.getsynctable<tentity> ();         }          public async task pushasync ()         {             try {                 await initialization;                 await context.synccontext.pushasync ();             } catch (mobileserviceinvalidoperationexception invalidoperationex) {                 debug.writeline (invalidoperationex.message);             } catch (mobileservicepushfailedexception pushfailedexception) {                 debug.writeline (pushfailedexception.message);             }         }          public async task pullasync<tentity> (imobileservicetablequery<tentity> query)         {             try {                 await initialization;                 imobileservicesynctable<tentity> entitytable = await gettableasync<tentity> ();                 await entitytable.pullasync (typeof(tentity).tostring (), query); // never returns, no exception caught or thrown.                 await entitytable.purgeasync ();             } catch (mobileserviceinvalidoperationexception preconditionfailedex) {                 debug.writeline (preconditionfailedex.message);             } catch (exception ex) {                 debug.writeline (ex.message);             }         }          public async task syncasync<tentity> ()         {             await pushasync ();             imobileservicesynctable<tentity> synctable = await gettableasync<tentity> ();             await pullasync (synctable.createquery ());         }     } 

i use singleton baserepository have base class 5 different entity repositories.

public abstract class baserepository<tentity> : irepository<tentity> tentity : class     {         protected azuremobiledatacontext mobileservicecontext { { return azuremobiledatacontext.instance; } }          protected virtual task pushasync ()         {             return mobileservicecontext.pushasync ();         }          protected virtual task pullasync (imobileservicetablequery<tentity> query)         {             return mobileservicecontext.pullasync (query);         }          public virtual async task<dataobjectresponse<ienumerable<tentity>>> findasync (expression<func<tentity, bool>> predicate)         {             imobileservicesynctable<tentity> synctable = await mobileservicecontext.gettableasync<tentity> ();             await pullasync (synctable.createquery ());             ienumerable<tentity> entities = await synctable.where (predicate).toenumerableasync ();             return new dataobjectresponse<ienumerable<tentity>> (entities);         } } 

the users repository.

public class usersazurerepository : baserepository<user>, iusersrepository     {         public usersazurerepository ()         {         }          public async task<dataobjectresponse<user>> findbyidasync (string entityid)         {             dataobjectresponse<ienumerable<user>> users = await findasync (p => p.id == entityid);             return new dataobjectresponse<user>(users.data.firstordefault ());         }     } 

a dataservice facade class containing getuserbyid method.

public async task<usermodel> getuserbyid (string userid)         {             dataobjectresponse<user> users = await usersrepository.findbyidasync (userid);             usermodel usermodel = mapper.map<user, usermodel> (users.data);             return usermodel;         } 

users view model method.

public async task<usermodel> getusersasync() // testing purposes         {             usermodel user = await _dataservice.getuserbyid("032beb3b-1cbf-4a0d-809c-a25c71139c55");              if (user != null) {                 debug.writeline ("user loaded: {0}", user.id);             }             return user;         } 

call ios uiviewcontroller.

public async override void viewdidload ()         {             base.viewdidload ();              usermodel user = await viewmodel.getusersasync ();         } 

the azuremobiledatacontext serves more thread safe wrapper imobileserviceclient context operations, making sure not multiple threads try initialize database (i had exception when using directly baserepository<t> before).

i'm not sure here might problem is. suspect wrapper not best solution , recommendations welcome.

any other ways debug pullasync method?

[edit]

the local sqlite database syncs table data remote service still call doesn't return.

the problem in azure mobile service, server side.

i returning tablecontroller ienumerable sdk uses odata query expressions it's own job, returning ienumerable not sufficient, changing iqueryable fixed issue of continuous looping when pulling data.

i believe server return type shouldn't related sdk way works.


Comments