Könntest du bitte so freundlich sein, mich auf den Fehler hinzuweisen, warum ich den folgenden Code synchron laufen lasse und UI bei asynchronen Anfragen an DB blockiere? Danke im Voraus.Wie kann man db-Daten asynchron lesen?
Meine Viewmodel:
public virtual bool MerchantsLoading { get; set; }
public virtual ObservableCollectionCore<Merchant> Merchants { get; set; }
public MerchantViewModel { //constructor
MerchantsLoading = true;
Merchants = SQLite.GetMerchants().Result;
SQLite.GetMerchants().ContinueWith(task => MerchantsLoading = false);
}
Meine Ansicht:
...
<dxg:GridControl ShowLoadingPanel="{Binding MerchantsLoading}" ItemsSource="{Binding Merchants}".../>
...
SQLite.GetMerchants():
public static async Task<ObservableCollectionCore<Merchant>> GetMerchants()
{
SQLiteConnection SqlConnection = new SQLiteConnection(MerchantDB);
var Merchants = new ObservableCollectionCore<Merchant.Merchant>();
try
{
await SqlConnection.OpenAsync();
SQLiteCommand myCommand = new SQLiteCommand("select * from merchant", SqlConnection);
DbDataReader myReader = await myCommand.ExecuteReaderAsync();
while (myReader.Read())
{
Merchants.Add(new Merchant.Merchant
{
ID = Convert.ToInt32(myReader["ID"]),
Name = Convert.ToString(myReader["Name"])
});
}
}
catch (Exception ex)
{
Messenger.Default.Send(new LogMessage { Message = "Ошибка в процедуре GetMerchants" });
Messenger.Default.Send(new LogMessage { Message = ex.ToString() });
}
finally
{
SqlConnection.Close();
}
return Merchants;
}
ich neue Funktion hinzugefügt haben, die auf UserControl.Loaded gebrannt Ereignis, aber UI ist immer noch blockiert (Viewmodel-Konstruktor ist jetzt leer):
public async void Loaded()
{
MerchantsLoading = true;
Merchants = await SQLite.GetMerchants();
await SQLite.GetMerchants().ContinueWith(task => MerchantsLoading = false);
}
Loaded-Ereignis ausgelöst durch EventToCommand von DevExpress MVVM Framework:
<UserControl xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:ViewModels="clr-namespace:ORBKWorker.Merchant"
xmlns:Helpers="clr-namespace:ORBKWorker.Helpers"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
x:Class="ORBKWorker.Merchant.MerchantView"
mc:Ignorable="d"
DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModels:MerchantViewModel}}"
d:DesignHeight="800" d:DesignWidth="1920">
<UserControl.Resources>
<Helpers:IntToEmailType x:Key="IntToEmailType"/>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding LoadedCommand}"/>
</dxmvvm:Interaction.Behaviors>
<Grid>...
Endlich ist es mit Background zu tun beschlossen:
public void GetMerchants()
{
MerchantsLoading = true;
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += (sender, args) => Merchants = SQLite.GetMerchants();
bgw.RunWorkerCompleted += (sender, args) => MerchantsLoading = false;
bgw.RunWorkerAsync();
}
Nach meinem Wissen sollte Ihre wartende Funktion Aufgabe, t Hut ist erwarten sollte mit einer Funktion verwendet werden, um eine Aufgabe zurückzugeben. http://blog.stephencleary.com/2012/02/async-and-await.html – AnjumSKhan