FetFrumos
FetFrumos

Reputation: 5944

Sqlite.net async - how use in Xamarin?

I created an app for Android and Windows Phone. For data access i'm using sqllite.net async. I created the simple example solution with a PCL liblary, Xamarin Android project and Windows Phone 8 silverligth project. This is my DataService in PCL:

public  class DataService
{
     private SQLiteAsyncConnection _dbConnection;
     public DataService(ISQLitePlatform platform, string path)
    {
        var connectionFactory = new Func<SQLiteConnectionWithLock>
                (() => new SQLiteConnectionWithLock(platform, new     SQLiteConnectionString(path, true)));
        _dbConnection = new SQLiteAsyncConnection(connectionFactory);
    }
    public async Task Initialize()
    {
        await _dbConnection.CreateTableAsync<ToDo>().ContinueWith(t =>
        {
           Debug.WriteLine("Create");
        });
    }
    public async Task<int> AddNewToDo(ToDo item)
    {
        var result = await _dbConnection.InsertAsync(item);
        return result;
    } 

    public async Task<List<ToDo>> GetAllToDos()
    {
        var result = await _dbConnection.Table<ToDo>().OrderByDescending(t => t.TimeStamp).ToListAsync();
        return result;
    }
    ....
  }

This is using in Windows Phone:

    private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        var db = new DataService(new SQLitePlatformWP8(), "my.db");
        await db.Initialize();
        await db.AddNewToDo(new ToDo {Text = "Hello world"});
        var items = await db.GetAllToDos();
        Debug.WriteLine("Count - {0}",items.Count);
    } 

output in Windows Phone:

Create
Count - 1

It is ok. Debugging is works.

This is using in Xamarin Android:

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button>(Resource.Id.MyButton);

        button.Click += delegate
        {
            TestDb();
        };
    }

    private async void TestDb()
    {
        string documentsPath =        System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); 
        var path = Path.Combine(documentsPath, "my.db");
        var db = new DataService(new SQLitePlatformAndroid(), path);
        await db.Initialize();
        await db.AddNewToDo(new ToDo { Text = "Hello world" });
        var items = await db.GetAllToDos();
        Console.WriteLine("count - {0}",items.Count);
    }

output:

 [0:] 
 Create
 [0:] Create
 02-18 00:46:01.167 I/mono-stdout(19234): Create
 count - 1
 02-18 00:46:01.675 I/mono-stdout(19234): count - 1

Why are invoked more than once? Debugging not working. When I stop at code with await, next step just drops out of the method without touching my return calls or anything.

This is a simple example, and I do not understand why this is happening. Maybe I'm doing something wrong.

Upvotes: 4

Views: 7481

Answers (1)

jzeferino
jzeferino

Reputation: 7850

Your code have a problem:

button.Click += delegate
{
    TestDb();
};

TestDb is an async method and you're calling it asynchronously without the await.

This will make the call to TestDb to happens after you leave the Click event code.

I suggest you to await the call:

button.Click += async delegate
{
    await TestDb();
};

Upvotes: 3

Related Questions