I am having trouble with the async operation of the interface

Dec 12, 2013 at 3:59 PM
Hi,

I have integrated this interface with app I have done in VB for the Windows Phone. I have also done this same app on the iPhone and the Android.

I am having trouble coordinating the open's , read's and write's in my app due to the async operation of the interface. For example , I will request the data base to open , and my code will continue on to a read because the open has not been completed. This has to do with the async requests. By the way , on the iPhone and the Android , this does not happen , when you request an open to the data base of a read , the app does not continue execution until that operation is complete. Within the app , this is the only logical way to design code , and in this app consisting of about 20 individual functions (pages) at the beginning of each function , I first have to open the data base , then read the data and once the data is read then perform calculations and then at the end write the data back to the data base.

The way it has worked with this interface , I have sometimes have had to execute a wait loop to ensure the database is open before proceeding. This question I have is - is there a way to use this interface without using async operations so one can sequentially execute the code in order and one does not have to worry about async operation , in you comments you say that async operation makes a much smoother interface to the database but in my case it has become a nightmare of programming. Seems that there ought to be a better way. Maybe I am missing something.

I also have the question - can one use the direct or lower level calls to the SQLite library via your interface instead of using the wrapper. I know on the windows 8 desktop version of my app I am able to call directly the SQLite library at the lowest level. Also , on the desktop one does not have to worry about aync operation of I/o to the SQLite library.

Your help would be greatly appreciated.

Thanks Jerry
Coordinator
Dec 13, 2013 at 10:32 AM

Jerry,

A line that contains a call to an async method acts like a synchronous call as long as you call it using the await keyword – so within a method, there is no special difficulty with using async methods.

If you create a method yourself that contains calls to other async methods, and you change the return type of the method to be Task or Task<T> (for example, if a method returned an int before, change it to return a Task<int>) then you can call your new method again using await and nothing bad will happen! It will work the same as synchronous code.

The difficulty comes with code that sits inside an event handler method (so that’s a significant percentage of most XAML-based apps). An event handler method is essentially a method that returns void and which the caller calls in a ‘fire-and-forget’ fashion. There’s actually no way of modifying the way that event handlers are called to somehow work in the await keyword into there. The result is that, the caller fires an event – for example, the framework fires the Application_Launching event – and your code in your Application_Launching event handler starts to execute in a synchronous fashion up to the point where it encounters a call to an async method, such as await mydatabase.OpenAsync(). At that point, your event handler method suspends and returns to the caller which carries on as if the event handler code had executed to completion. Your event handler code will resume later on when the database open has completed, but by then the original caller – the framework – doesn’t care and has gone onto execute other things, such as loading your page and executing the code for that. This is why you can sometimes get sequencing problems.

The answer is to implement some kind of gatekeeper method to ensure that the database is fully prepared and open before anyone tries to read from it. Download the sample on my blog post: SQLite-WinRT:Database programming on Windows Phone and Windows 8 for an example of how I did it – look at the GetDatabaseAsync() method in app.xaml.cs – that waits until the LoadDatabase method has set the DBLoaded ManualResetEvent.

See my other post that talks about this problem some more: Beware the perils of async/await in application lifecycle event handlers (in fact in *any* event handlers)

Andy