Search code examples
c#sqlitemvvmxamarin.formssqlite-net-pcl

How to use asynchronous method in constructor when .Result() makes the method hang?


I have an AppearingCommand called when a Page appears in my Xamarin.Forms project, that eventually executes the following sqlite-net-pcl line: (I already have a mechanism coping with loading time)

AppearingCommand = new Command( async() => {
    //...
    var data = await db.Table<PlantCategory>().ToListAsync();
    //...
}

I want to move this method to the constructor, but I cannot do it, as it hangs if it is executed synchronously:

ctor() {
    //...
    var data = db.Table<PlantCategory>().ToListAsync().Result;
    //...
}

The line never returns (I am guessing because of a deadlock or something). What are other options that I have if I want to execute this line inside the constructor?


Solution

  • Simple. Don't.

    Instead, add a post-construction method like async ValueTask InitAsync() and call that with await.

    You could hide this behind a static ValueTask<Whatever> CreateAsync(...) method that you call instead of new Whatever(...), i.e.

    class Whatever {
        private Whatever(...) { ... } // basic ctor
        private async ValueTask InitAsync(...) { ... } // async part of ctor
    
        public static async ValueTask<Whatever> CreateAsync(...) {
            var obj = new Whatever(...);
            await obj.InitAsync(...);
            return obj;
        }
    }