не могли бы вы быть настолько добрыми, чтобы указать мне на ошибку, почему у меня следующий код работает синхронно и блокирует пользовательский интерфейс во время асинхронного запроса к БД? Заранее спасибо.Каков правильный способ чтения dns-данных async?
Мои 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);
}
Мой Вид:
...
<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;
}
Я добавил новую функцию, которая обстреливали UserControl.Loaded событие, но UI по-прежнему заблокирован (конструктор viewmodel теперь пуст):
public async void Loaded()
{
MerchantsLoading = true;
Merchants = await SQLite.GetMerchants();
await SQLite.GetMerchants().ContinueWith(task => MerchantsLoading = false);
}
Loaded событие обстреляно EventToCommand из 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>...
Наконец решил сделать это с BackgroundWorker:
public void GetMerchants()
{
MerchantsLoading = true;
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += (sender, args) => Merchants = SQLite.GetMerchants();
bgw.RunWorkerCompleted += (sender, args) => MerchantsLoading = false;
bgw.RunWorkerAsync();
}
Насколько я знаю, ваша ожидающая функция должна вернуть Task, t hat ждет, когда функция возвращает функцию Task. http://blog.stephencleary.com/2012/02/async-and-await.html – AnjumSKhan