.NET MAUI — разрывы SQLite-net-PCL CreateTableAsync ⇐ C#
-
Anonymous
.NET MAUI — разрывы SQLite-net-PCL CreateTableAsync
Ранее у меня возникала проблема, когда все мое приложение зависало после вызова db.CreateTableAsync в файле Service.cs после выполнения этого руководства. После устранения этой проблемы с помощью этого решения приложение перестало зависать, но CreateTableAsync, похоже, ничего не делает и просто выходит из задач Init и AddPin. В одной и той же среде выполнения, если бы я попытался запустить задачу AddPin несколько раз, в первый раз CreateTableAsync сломался бы и последующие разы после начального, будет вызвана остальная часть AddPin (потому что db != null), и это стоит отметить что независимо от того, сколько раз я запускаю AddPin, идентификатор не увеличивается.
Туалет.cs
с использованием SQLite; использование системы; использование System.Collections.Generic; используя System.Linq; использование System.Text; использование System.Threading.Tasks; пространство имен Dook.Model { общественный класс, туалет { [SQLite.PrimaryKey, SQLite.AutoIncrement] [Столбец("Идентификатор")] общественный ИНТ Id {получить; набор; } [Столбец("Имя")] общедоступная строка Имя {get; набор; } [Столбец("Адрес")] общедоступная строка Адрес {get; набор; } [Столбец("Имя пользователя")] публичная строка Имя пользователя {get; набор; } [Столбец("Местоположение")] общедоступное местоположение PinLocation {get; набор; } } } ResroomService.cs
с использованием Dook.Model; использование SQLite; использование системы; использование System.Collections.Generic; используя System.Linq; использование System.Text; использование System.Threading.Tasks; пространство имен Dook.Services { общедоступный статический класс RestroomService { статическая база данных SQLiteAsyncConnection; статическая асинхронная задача InitAsync() { если (дб! = ноль) возвращаться; var DatabasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db"); db = новый SQLiteAsyncConnection (databasePath); ждут db.CreateTableAsync(); Debug.WriteLine("Брух"); } общедоступная статическая асинхронная задача AddPinAsync (имя строки, адрес строки, имя пользователя строки, местоположение) { дождитесь InitAsync(); var туалет = новый туалет { Имя = имя, Адрес = адрес, Имя пользователя = имя пользователя, PinLocation = местоположение }; вар идентификатор = ждут db.InsertAsync (туалет); } общедоступная статическая асинхронная задача RemovePinAsync (int id) { дождитесь InitAsync(); ждут db.DeleteAsync(id); } общедоступная статическая асинхронная задача GetPinAsync() { дождитесь InitAsync(); вар туалет = ждут db.Table().ToListAsync(); возвратный туалет; } } } MainPage.xaml.cs
пространство имен Dook; использование Microsoft.Maui.Controls.Maps; использование Microsoft.Maui.Maps; использование System.Diagnostics; используя Map = Microsoft.Maui.Controls.Maps.Map; использование Dook.ViewModel; использование Dook.Model; общедоступный частичный класс MainPage: ContentPage { публичная главная страница() { ИнициализироватьКомпонент(); ПереместитьMapLocation(); } частная пустота GoToLocation_Button (отправитель объекта, EventArgs e) { ПереместитьMapLocation(); } Private void OnMapClicked (отправитель объекта, MapClickedEventArgs e) { вар vm = (MainViewModel)this.BindingContext; если (vm.AddCommand.CanExecute(e.Location)) vm.AddCommand.ExecuteAsync(e.Location); } частная пустота RefreshButton_Clicked (отправитель объекта, EventArgs e) { вар vm = (MainViewModel)this.BindingContext; vm.RefreshCommand.ExecuteAsync(); } частная пустота MoveMapLocation() { //Функция, позволяющая избежать шаблонного кода MapSpan mapSpan = новый MapSpan(MainViewModel.GetLocation(), 0.01, 0.01); mainmap.MoveToRegion(mapSpan); } } MainPage.xaml
MainViewModel.cs
с использованием системы; использование System.Collections.Generic; используя System.Linq; использование System.Text; использование System.Threading.Tasks; использование Microsoft.Maui.Controls.Maps; использование Microsoft.Maui.Maps; используя Map = Microsoft.Maui.Controls.Maps.Map; использование Dook.Model; использование Dook.Services; использование MvvmHelpers; использование MvvmHelpers.Commands; использование CommunityToolkit.Maui.Core.Extensions; пространство имен Dook.ViewModel { общедоступный класс MainViewModel: BaseViewModel { public ObservableRangeCollection Туалет {get; набор; } общественный AsyncCommand RefreshCommand {get; } общественный AsyncCommand AddCommand {get; } общественный AsyncCommand RemoveCommand {get; } общественная MainViewModel() { Title = "Контроллер карты"; Туалет = новый ObservableRangeCollection(); AddCommand = новый AsyncCommand(AddAsync); RemoveCommand = новый AsyncCommand(RemoveAsync); RefreshCommand = новая AsyncCommand (RefreshAsync); } асинхронная задача AddAsync (Местоположение currentLocation) { var name = await App.Current.MainPage.DisplayPromptAsync("Имя местоположения", "Имя местоположения"); // var адрес = "Широта: {pinlocation.Latitude}, Долгота: {pinlocation.Longitude}, Высота: {location.Altitude}"; адрес вар = "тест"; var username = await App.Current.MainPage.DisplayPromptAsync("Имя пользователя", "Имя пользователя туалетного сумматора"); вар местоположение = currentLocation; if (имя == null || адрес == null || имя пользователя == null) { return; } ждут RestroomService.AddPinAsync(имя, адрес, имя пользователя, местоположение); ожидайте RefreshAsync(); } асинхронная задача RemoveAsync (туалет в туалете) { ждут RestroomService.RemovePinAsync(restroom.Id); ожидайте RefreshAsync(); } асинхронная задача RefreshAsync() { IsBusy = правда; ждать Task.Delay(2000); Туалет.Очистить(); вар туалеты = ждут RestroomService.GetPinAsync(); Restroom.AddRange(туалеты); IsBusy = ложь; } общедоступное статическое местоположение GetLocation() { пытаться { Расположение местоположения = новое(); местоположение = Геолокация.По умолчанию.GetLastKnownLocationAsync().Результат; если (местоположение!= ноль) место возврата; } поймать (Исключение ex) { Debug.WriteLine($"Невозможно получить местоположение: {ex.Message}"); Application.Current.MainPage.DisplayAlert("Ошибка!", ex.Message, "ОК"); } вернуть ноль; } } }
Ранее у меня возникала проблема, когда все мое приложение зависало после вызова db.CreateTableAsync в файле Service.cs после выполнения этого руководства. После устранения этой проблемы с помощью этого решения приложение перестало зависать, но CreateTableAsync, похоже, ничего не делает и просто выходит из задач Init и AddPin. В одной и той же среде выполнения, если бы я попытался запустить задачу AddPin несколько раз, в первый раз CreateTableAsync сломался бы и последующие разы после начального, будет вызвана остальная часть AddPin (потому что db != null), и это стоит отметить что независимо от того, сколько раз я запускаю AddPin, идентификатор не увеличивается.
Туалет.cs
с использованием SQLite; использование системы; использование System.Collections.Generic; используя System.Linq; использование System.Text; использование System.Threading.Tasks; пространство имен Dook.Model { общественный класс, туалет { [SQLite.PrimaryKey, SQLite.AutoIncrement] [Столбец("Идентификатор")] общественный ИНТ Id {получить; набор; } [Столбец("Имя")] общедоступная строка Имя {get; набор; } [Столбец("Адрес")] общедоступная строка Адрес {get; набор; } [Столбец("Имя пользователя")] публичная строка Имя пользователя {get; набор; } [Столбец("Местоположение")] общедоступное местоположение PinLocation {get; набор; } } } ResroomService.cs
с использованием Dook.Model; использование SQLite; использование системы; использование System.Collections.Generic; используя System.Linq; использование System.Text; использование System.Threading.Tasks; пространство имен Dook.Services { общедоступный статический класс RestroomService { статическая база данных SQLiteAsyncConnection; статическая асинхронная задача InitAsync() { если (дб! = ноль) возвращаться; var DatabasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db"); db = новый SQLiteAsyncConnection (databasePath); ждут db.CreateTableAsync(); Debug.WriteLine("Брух"); } общедоступная статическая асинхронная задача AddPinAsync (имя строки, адрес строки, имя пользователя строки, местоположение) { дождитесь InitAsync(); var туалет = новый туалет { Имя = имя, Адрес = адрес, Имя пользователя = имя пользователя, PinLocation = местоположение }; вар идентификатор = ждут db.InsertAsync (туалет); } общедоступная статическая асинхронная задача RemovePinAsync (int id) { дождитесь InitAsync(); ждут db.DeleteAsync(id); } общедоступная статическая асинхронная задача GetPinAsync() { дождитесь InitAsync(); вар туалет = ждут db.Table().ToListAsync(); возвратный туалет; } } } MainPage.xaml.cs
пространство имен Dook; использование Microsoft.Maui.Controls.Maps; использование Microsoft.Maui.Maps; использование System.Diagnostics; используя Map = Microsoft.Maui.Controls.Maps.Map; использование Dook.ViewModel; использование Dook.Model; общедоступный частичный класс MainPage: ContentPage { публичная главная страница() { ИнициализироватьКомпонент(); ПереместитьMapLocation(); } частная пустота GoToLocation_Button (отправитель объекта, EventArgs e) { ПереместитьMapLocation(); } Private void OnMapClicked (отправитель объекта, MapClickedEventArgs e) { вар vm = (MainViewModel)this.BindingContext; если (vm.AddCommand.CanExecute(e.Location)) vm.AddCommand.ExecuteAsync(e.Location); } частная пустота RefreshButton_Clicked (отправитель объекта, EventArgs e) { вар vm = (MainViewModel)this.BindingContext; vm.RefreshCommand.ExecuteAsync(); } частная пустота MoveMapLocation() { //Функция, позволяющая избежать шаблонного кода MapSpan mapSpan = новый MapSpan(MainViewModel.GetLocation(), 0.01, 0.01); mainmap.MoveToRegion(mapSpan); } } MainPage.xaml
MainViewModel.cs
с использованием системы; использование System.Collections.Generic; используя System.Linq; использование System.Text; использование System.Threading.Tasks; использование Microsoft.Maui.Controls.Maps; использование Microsoft.Maui.Maps; используя Map = Microsoft.Maui.Controls.Maps.Map; использование Dook.Model; использование Dook.Services; использование MvvmHelpers; использование MvvmHelpers.Commands; использование CommunityToolkit.Maui.Core.Extensions; пространство имен Dook.ViewModel { общедоступный класс MainViewModel: BaseViewModel { public ObservableRangeCollection Туалет {get; набор; } общественный AsyncCommand RefreshCommand {get; } общественный AsyncCommand AddCommand {get; } общественный AsyncCommand RemoveCommand {get; } общественная MainViewModel() { Title = "Контроллер карты"; Туалет = новый ObservableRangeCollection(); AddCommand = новый AsyncCommand(AddAsync); RemoveCommand = новый AsyncCommand(RemoveAsync); RefreshCommand = новая AsyncCommand (RefreshAsync); } асинхронная задача AddAsync (Местоположение currentLocation) { var name = await App.Current.MainPage.DisplayPromptAsync("Имя местоположения", "Имя местоположения"); // var адрес = "Широта: {pinlocation.Latitude}, Долгота: {pinlocation.Longitude}, Высота: {location.Altitude}"; адрес вар = "тест"; var username = await App.Current.MainPage.DisplayPromptAsync("Имя пользователя", "Имя пользователя туалетного сумматора"); вар местоположение = currentLocation; if (имя == null || адрес == null || имя пользователя == null) { return; } ждут RestroomService.AddPinAsync(имя, адрес, имя пользователя, местоположение); ожидайте RefreshAsync(); } асинхронная задача RemoveAsync (туалет в туалете) { ждут RestroomService.RemovePinAsync(restroom.Id); ожидайте RefreshAsync(); } асинхронная задача RefreshAsync() { IsBusy = правда; ждать Task.Delay(2000); Туалет.Очистить(); вар туалеты = ждут RestroomService.GetPinAsync(); Restroom.AddRange(туалеты); IsBusy = ложь; } общедоступное статическое местоположение GetLocation() { пытаться { Расположение местоположения = новое(); местоположение = Геолокация.По умолчанию.GetLastKnownLocationAsync().Результат; если (местоположение!= ноль) место возврата; } поймать (Исключение ex) { Debug.WriteLine($"Невозможно получить местоположение: {ex.Message}"); Application.Current.MainPage.DisplayAlert("Ошибка!", ex.Message, "ОК"); } вернуть ноль; } } }
Мобильная версия