Übung: Asynchrones Verwenden von SQLite
Die Anwendung funktioniert gut, wenn aber die Datenbank viele Zeilen enthält, kann die Benutzeroberfläche nicht mehr reagieren, während die App Datenbankabfragen und andere Vorgänge ausführt. In dieser Übung konvertieren Sie die Anwendung von der synchronen SQLite-API in die asynchrone Version. Dadurch bleibt Ihre Anwendung immer reaktionsfähig, unabhängig davon, wie viele Abfragen an die Datenbank gesendet werden.
Erstellen einer asynchronen Verbindung
Öffnen Sie die Datei PersonRepository.cs im Projekt Personen.
Ändern Sie die Definition der
Init
-Methode so, dass sieasync
ist. Ändern Sie den Rückgabetyp der Methode inTask
.Ändern Sie die
conn
-Eigenschaft in einenSQLiteAsyncConnection
, und aktualisieren Sie den Code in derInit
-Methode, welche die Verbindung initialisiert.Ersetzen Sie den Aufruf der synchronen
CreateTable
-Methode durch die asynchroneCreateTableAsync
-Methode.Der vollständige Code sollte wie folgt aussehen:
private SQLiteAsyncConnection conn; private async Task Init() { if (conn != null) return; conn = new SQLiteAsyncConnection(_dbPath); await conn.CreateTableAsync<Person>(); }
Asynchrones Einfügen eines Elements in eine Tabelle
Ändern Sie die Definition der
AddNewPerson
-Methode inasync
. Ändern Sie den Rückgabetyp der Methode inTask
.Fügen Sie das
await
-Schlüsselwort zumInit
-Methodenaufruf hinzu, daInit
jetzt eineasync
-Methode ist.Aktualisieren Sie die
AddNewPerson
-Methode, um eine neuePerson
einzufügen, indem Sie einen asynchronen Einfügevorgang verwenden.Der Code sollte wie folgt aussehen:
using System.Threading.Tasks; ... public async Task AddNewPerson(string name) { int result = 0; try { // Call Init() await Init(); // basic validation to ensure a name was entered if (string.IsNullOrEmpty(name)) throw new Exception("Valid name required"); result = await conn.InsertAsync(new Person { Name = name }); StatusMessage = string.Format("{0} record(s) added [Name: {1})", result, name); } catch (Exception ex) { StatusMessage = string.Format("Failed to add {0}. Error: {1}", name, ex.Message); } }
Asynchrones Abrufen aller Elemente einer Tabelle
Ändern Sie die
GetAllPeople
-Methodendefinition. Diese Methode sollte einasync
-Objekt sein und einTask<List<Person>>
-Objekt zurückgeben.Fügen Sie das
await
-Schlüsselwort zumInit
-Methodenaufruf hinzu.Aktualisieren Sie die Methode so, dass die Ergebnisse mithilfe eines asynchronen Aufrufs zurückgegeben werden.
Der Code sollte wie folgt aussehen:
public async Task<List<Person>> GetAllPeople() { try { await Init(); return await conn.Table<Person>().ToListAsync(); } catch (Exception ex) { StatusMessage = string.Format("Failed to retrieve data. {0}", ex.Message); } return new List<Person>(); }
Speichern Sie die Datei PersonRepository.cs.
Testen der asynchronen Funktionalität
Erweitern Sie MainPage.xaml im Projektmappen-Explorer, und öffnen Sie die Datei MainPage.xaml.cs.
Ändern Sie beide Schaltflächenklick-Ereignishandler so, dass sie die asynchronen Methoden aus der
PersonRepository
-Klasse verwenden. Verwenden Sie dazu die Schlüsselwörterasync
undawait
:public async void OnNewButtonClicked(object sender, EventArgs args) { statusMessage.Text = ""; await App.PersonRepo.AddNewPerson(newPerson.Text); statusMessage.Text = App.PersonRepo.StatusMessage; } public async void OnGetButtonClicked(object sender, EventArgs args) { statusMessage.Text = ""; List<Person> people = await App.PersonRepo.GetAllPeople(); peopleList.ItemsSource = people; }
Speichern Sie die Datei MainPage.xaml.cs.
Erstellen Sie das Programm unter Windows und Android, und führen Sie es unter diesen Betriebssystemen auch aus, um zu überprüfen, ob es weiterhin wie zuvor funktioniert.