Как закрыть соединение SQLite в формах Xamarin? - PullRequest
0 голосов
/ 14 июня 2019

У меня есть код, который получает данные с моего сервера. Все данные будут вставлены в мою локальную базу данных (базу данных SQLite) один за другим. Каждый раз в целом я получаю эти две ошибки. Мои коды ниже, где всегда появляются исключения.

SQLite.SQLiteException: Busy
SQLite.SQLiteException: база данных заблокирована

Какова причина (причины), почему я всегда получаю эти исключения?

Обновление:
Я добавил await conn.CloseAsync (); в каждом конце кода это правильно?

вот мой первый код, он запросит у сервера, есть ли обновления, и если есть обновления, он вставит или заменит (обновит) данные в моей локальной базе данных:

var db = DependencyService.Get<ISQLiteDB>();
var conn = db.GetConnection();

string apifile = "sync-retailer-outlet-server-update-api.php";
var lastchecked = Preferences.Get("retaileroutletchangelastcheck", String.Empty, "private_prefs");
int count = 0;

var uri = new Uri(string.Format("http://" + domain + "/TBSApp/app_api/" + apifile + "?Host=" + host + "&Database=" + database + "&ContactID=" + contact + "&LastChecked=" + lastchecked, string.Empty));

try
{
    SyncStatus("Getting retailer outlet data from server");

    var response = await client.GetAsync(uri);

    if (response.IsSuccessStatusCode)
    {
        var content = await response.Content.ReadAsStringAsync();

        if (!string.IsNullOrEmpty(content))
        {
            var dataresult = JsonConvert.DeserializeObject<List<RetailerGroupData>>(content, settings);
            var datacount = dataresult.Count;

            for (int i = 0; i < datacount; i++)
            {
                SyncStatus("Saving retailer outlet server update to local database (" + (count + 1) + " out of " + dataresult.Count + ")");

                var item = dataresult[i];
                var retailerCode = item.RetailerCode;

                var insertdata = new RetailerGroupTable
                {
                    RetailerCode = retailerCode
                };

                await conn.InsertOrReplaceAsync(insertdata);

                count++;
            }
        }
    }
}
catch (Exception ex)
{
    Crashes.TrackError(ex);
}

await conn.CloseAsync();

Вот другой код, который создает таблицу локальной базы данных при каждой загрузке StartPage.

public async void CreateTableAsync()
    {
        try
        {
            var db = DependencyService.Get<ISQLiteDB>();
            var conn = db.GetConnection();

            if (conn != null)
            {
                try
                {
                    await conn.CreateTableAsync<UserTable>();
                    await conn.CreateTableAsync<ContactsTable>();
                    await conn.CreateTableAsync<ActivityTable>();
                    await conn.CreateTableAsync<CAFTable>();
                    await conn.CreateTableAsync<RetailerGroupTable>();
                    await conn.CreateTableAsync<UserEmailTable>();
                    await conn.CreateTableAsync<UserLogsTable>();
                    await conn.CreateTableAsync<SubscriptionTable>();
                    await conn.CreateTableAsync<ProvinceTable>();
                    await conn.CreateTableAsync<TownTable>();
                }
                catch (Exception ex)
                {
                    Console.Write("Creating table error " + ex.Message);
                }
            }
        }
        catch (Exception ex)
        {
            Crashes.TrackError(ex);
            await DisplayAlert("Application Error", "Error:\n\n" + ex.Message.ToString() + "\n\n Please contact your administrator", "Ok");
        }
    }

await conn.CloseAsync();

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

Согласно вашему описанию и коду, я предполагаю, что вы используете вставки в асинхронном стиле и работаете в разных потоках, поэтому время вставки истекает в ожидании завершения блокировки другой вставки. Вы можете использовать синхронные вставки, чтобы избежать этого условия.

0 голосов
/ 14 июня 2019
using (SQLiteConnection connection = db.GetConnection())
{
    // Do whatever you want to do with your active connection
}

Обратите внимание, что вы не можете повторно использовать это соединение за пределами области использования блока, и вам придется получать новое соединение таким же образом, когда вы в следующий раз захотите получить доступ к вашей базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...