Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

SQLite-net-pcl on cross platform app saves well on iOS but erratic on Android

I wonder if this is a common issue. I load data from a web service (MS SQL Database passing JSON) into my mobile app for off-line processing. This works perfectly in iOS. On Android, if I step through the code when persisting, it works fine. If I run without any breakpoints, some data is not always persisted. I have reverted to pack all the transactions into forced start and commit transactions using ExecuteAsync, tried to close the connection regularly but still inconsistent results. Are there any known issues? This is on Android v 7 (HUAWEI) phone and the project targets API 28 with minimum 23

Tagged:

Best Answer

Answers

  • JohnHardmanJohnHardman GBUniversity admin

    @lombarda said:
    I wonder if this is a common issue. I load data from a web service (MS SQL Database passing JSON) into my mobile app for off-line processing. This works perfectly in iOS. On Android, if I step through the code when persisting, it works fine. If I run without any breakpoints, some data is not always persisted. I have reverted to pack all the transactions into forced start and commit transactions using ExecuteAsync, tried to close the connection regularly but still inconsistent results. Are there any known issues? This is on Android v 7 (HUAWEI) phone and the project targets API 28 with minimum 23

    Sounds like you have a race condition in the code. You'd have to post a small piece of code that demonstrates the problem for anybody to be able to pinpoint it.

  • lombardalombarda Member ✭✭
    edited November 2019

    Thanks John
    Bit tricky but basically if I do this: (Lots of code excluded for simplification) - I lose 1 herd
    try
    {
    Herd[] remoteH = JsonConvert.DeserializeObject<Herd[]>(GetResponse());
    //For each herd, I add all the animals
    for (int i = 0; i < remoteH.Length; i++)
    {
    App.Database.AddHerd(remoteH[i]); //First persist the herd record itself in the herd loop.
    Animal[] remoteA = JsonConvert.DeserializeObject<Animal[]>(GetResponse());
    for (int ii = 0; ii < remoteA.Length; ii++)
    {
    App.Database.AddSyncAnimal(remoteA[ii]);
    }
    Group[] remoteG = JsonConvert.DeserializeObject<Group[]>(GetResponse());
    for (int ii = 0; ii < remoteG.Length; ii++)
    {
    GroupAnimal[] remoteGA = JsonConvert.DeserializeObject<GroupAnimal[]>(GetResponse());
    for (int iii = 0; iii < remoteGA.Length; iii++)
    {
    App.Database.AddGroupAnimal(remoteGA[iii]);
    }
    }
    }
    }

    I also tried to persist the herds first - this worked once then not?:

                Herd[] remoteH = JsonConvert.DeserializeObject<Herd[]>(GetResponse());
    
                for (int i = 0; i < remoteH.Length; i++)
                {
                    App.Database.AddHerd(remoteH[i]);
                }
    
                for (int i = 0; i < remoteH.Length; i++)
                {
    
                    Animal[] remoteA = JsonConvert.DeserializeObject<Animal[]>(GetResponse());
                    for (int ii = 0; ii < remoteA.Length; ii++)
                    {
                        App.Database.AddSyncAnimal(remoteA[ii]);
                    }
                    Group[] remoteG = JsonConvert.DeserializeObject<Group[]>(GetResponse());
                    for (int ii = 0; ii < remoteG.Length; ii++)
                    {
                        GroupAnimal[] remoteGA = JsonConvert.DeserializeObject<GroupAnimal[]>(GetResponse());
                        for (int iii = 0; iii < remoteGA.Length; iii++)
                        {
                            App.Database.AddGroupAnimal(remoteGA[iii]);
                        }
                    }
                }
            }
    

    All the DB stuff are the same format (eg):

        public void AddHerd(Herd item)
        {
            database.ExecuteAsync("begin transaction");
            sql.Clear();
            sql.AppendFormat("insert into Herd (uid, authorisedEntity, herdName) values ({0}, {1}, '{2}')", item.uid,   
        item.authorisedEntity, item.herdName);
            database.ExecuteAsync(sql.ToString());
            database.ExecuteAsync("commit transaction");
        }
    

    One other thing I tried that seems to be more stable is to do all the database operations using the synchronous methods so I suspect that the potential race condition may have been caused by too many async tasks which are not really needed in context or perhaps my grasp of Tasks and async is a little scratchy

  • lombardalombarda Member ✭✭

    Excellent thanks John. Will spend some time swotting the Task and Async thing. For me it seems awaiting async pretty much resolves to sync. Many thanks for going to the trouble of helping to teach old dogs new tricks.

  • JohnHardmanJohnHardman GBUniversity admin
    edited November 2019

    @lombarda said:
    For me it seems awaiting async pretty much resolves to sync

    Not if the async method being called (or any method directly or indirectly called by it) starts a new Task internally. It just hides away the detail of what is going on, so that code looks sequential, making it easier to write/maintain.

Sign In or Register to comment.