Can Mono.Data.SQLite share the connection in multithread?

Hello,

I use Google Maps API for Android v2 with MBTiles format data as tilesource.
MBTiles is sqlite file, so I access it from GMaps API's GetTile methods.
They are called parallel, in multithread.

First, I try to share connection object with all method calls, so code like below:

public class MBTilesTileProvider : Java.Lang.Object, Android.Runtime.IJavaObject, IDisposable, ITileProvider
{
    private SqliteConnection Conn;

    public MBTilesTileProvider (string _mbtilesFileName) : base ()
    {
        ....

        SqliteConnection.SetConfig(SQLiteConfig.MultiThread);
        var Conn = new SqliteConnection( "Data Source=" + this.mbtilesFilePath);
        Conn.Open();
    }

    public Tile GetTile(int x, int y, int zoom)
    {
        var Cmd = Conn.CreateCommand(); <= Error occurs here.
        Cmd.CommandText = "SELECT tile_data FROM tiles WHERE tile_column = @column AND tile_row = @row AND zoom_level = @zoom";
        Cmd.Parameters.AddWithValue ("@column", x);

        ....

        Cmd.Dispose();
    }

    ~MBTilesTileProvider() 
    {
        Conn.Close();
        Conn.Dispose();
    }
}

But, this code spawn error like this.

System.Diagnostics.Debugger.Mono_UnhandledException (ex={System.NullReferenceException: Object reference not set to an instance of an object
at MyApp.MBTilesTileProvider.GetTile (int,int,int) [0x00000] in /Users/me/Projects/MyApp/MyApp/MBTilesTileProvider.cs:74
at Android.Gms.Maps.Model.ITileProviderInvoker.n_GetTile_III (intptr,intptr,int,int,int) [0x00008] in /Users/me/Dropbox/dev/monodroid-samples/MapsAndLocationDemo_v2/GooglePlayServices/obj/Debug/generated/src/Android.Gms.Maps.Model.ITileProvider.cs:106
at (wrapper dynamic-method) object.e51c4b86-bb0d-4ee8-9535-06f5a3e17ab2 (intptr,intptr,int,int,int) <IL 0x00023, 0x00063>
}) in 
object.e51c4b86-bb0d-4ee8-9535-06f5a3e17ab2 (arg0=0x5cc53e70, arg1=0x30300001, arg2=6, arg3=8, arg4=4) in 
MyApp.MBTilesTileProvider.GetTile (x=6, y=8, zoom=4) in /Users/me/Projects/MyApp/MyApp./MBTilesTileProvider.cs:74
Android.Gms.Maps.Model.ITileProviderInvoker.n_GetTile_III (jnienv=0x5cc53e70, native__this=0x30300001, p0=6, p1=8, p2=4) in /Users/me/Dropbox/dev/monodroid-samples/MapsAndLocationDemo_v2/GooglePlayServices/obj/Debug/generated/src/Android.Gms.Maps.Model.ITileProvider.cs:106
object.e51c4b86-bb0d-4ee8-9535-06f5a3e17ab2 (arg0=0x5cc53e70, arg1=0x30300001, arg2=6, arg3=8, arg4=4) in

After I change the code like below, it become to work, but it is too slow.

public class MBTilesTileProvider : Java.Lang.Object, Android.Runtime.IJavaObject, IDisposable, ITileProvider
{
    public MBTilesTileProvider (string _mbtilesFileName) : base ()
    {
        ....

        SqliteConnection.SetConfig(SQLiteConfig.MultiThread);
    }

    public Tile GetTile(int x, int y, int zoom)
    {
        var Conn = new SqliteConnection( "Data Source=" + this.mbtilesFilePath);
        Conn.Open();

        var Cmd = Conn.CreateCommand(); <= Error occurs here.
        Cmd.CommandText = "SELECT tile_data FROM tiles WHERE tile_column = @column AND tile_row = @row AND zoom_level = @zoom";
        Cmd.Parameters.AddWithValue ("@column", x);

        ....

        Cmd.Dispose();
        Conn.Close();
        Conn.Dispose();
    }
}

Can't I share the connection of SqliteConnection in multithread environment?

Best Answer

Answers

Sign In or Register to comment.