Я работаю над мобильным приложением Xamarin, используя .NET Framework и SQLite.NET-PCL. Моя форма XAML использует архитектуру MVVM, в моей основной форме я пытаюсь отобразить все фильмы в ListView, сначала я убедился, что само представление работает правильно, и теперь я пытаюсь подключить его к моей службе БД. Когда служба БД инициализируется и пытается создать любую таблицу с помощью CreateTableAsyc(), программа застревает в этой функции даже после того, как кажется, что она прошла успешно.
Первоначально я думал, что это связано с использованием созданных классов в качестве свойств, которые SQLite не поддерживает, поэтому я исправил это. Затем я проверил, не связано ли это с использованием аппаратного ускорения, поэтому я включил его. Затем я попытался выполнить отладку с помощью ContinueWith() и напечатал результат в консоли отладки, он говорит «Перенесено», но никогда не выходит из функции. Горячая перезагрузка Xamarin XAML затем истекает. Что может быть причиной этого?
Пример одного из типов:
using SQLite;
public class Movie
{
public Movie() {}
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Title { get; set; }
public DateTime Length { get; set; }
}
DBService
using Xamarin.Essentials;
public static class DBService
{
private static SQLiteAsyncConnection dbConn;
public static async Task Init()
{
if (dbConn != null)
{
return;
}
string databasePath = Path.Combine(FileSystem.AppDataDirectory, "Movies.db");
dbConn = new SQLiteAsyncConnection(databasePath, false);
await dbConn.CreateTableAsync<Movie>().ContinueWith(results =>
{
Debug.WriteLine(results.Result.ToString()); // This prints migrated
});
Debug.WriteLine("After table created"); // This never prints
}
public static async Task<IEnumerable<Movie>> GetMovies()
{
await Init();
return await dbConn.Table<Movie>().ToListAsync();
}
}
MovieViewModel (Модель просмотра для основного вида)
public class MovieViewModel
{
public List<Movie> Movies { get; set; }
public MovieViewModel ()
{
Movies = (List<Movie>)DBService.GetMovies().Result;
}
}





Оберните ожидаемое во что-то, что запускается после возврата конструктора:
MainThread.BeginInvoke(async () => Movies = (await DBService.GetMovies()).ToList() );
Дополнительно:GetMovies может вернуть список, соответствующий объявлению Movies. Тогда не нужно было бы ни .ToList(), ни (List<Movie>) приведения:
public static async Task<List<Movie>> GetMovies() { ... }
MainThread.BeginInvoke(async () => Movies = await DBService.GetMovies() );
Спасибо за решение и необязательное предложение, в итоге я переключился на ObservableCollection для захвата событий при его обновлении, поэтому он не приводит. Я использую конструктор с аргументом IEnumerable.
не вызывать асинхронный метод в конструкторе виртуальной машины