Я хочу, чтобы индикатор загрузки начинался сразу перед выполнением метода. Выполнение метода связано с работой каркаса сущности, поэтому я не могу (не могу) поместить этот тип кода в новый поток. Структура сущности bc не является потокобезопасной. Поэтому в основном в приведенном ниже методе я хочу, чтобы первая строка выполнялась и обновлялась пользовательский интерфейс, а затем возвращалась и выполняла остальную часть кода. Есть идеи?
public async void LoadWizard()
{
IsLoading = true; //Need the UI to update immediately
//Now lets run the rest (This may take a couple seconds)
StartWizard();
Refresh();
}
Я не могу этого сделать:
public async void LoadWizard()
{
IsLoading = true; //Need the UI to update immediately
await Task.Factory.StartNew(() =>
{
//Now lets run the rest (This may take a couple seconds)
StartWizard();
Refresh(); //Load from entityframework
});
//This isn't good to do entityframework in another thread. It breaks.
}
Предполагая, что видимость вашего занятого индикатора привязана к свойству IsLoading, вы делаете "что-то" неправильно в методе StartWizard или Refresh. Методы StartWizard и Refresh должны загружать только данные из вашего источника данных. У вас не должно быть никакого кода, который изменяет состояние пользовательского интерфейса в ваших методах загрузки. Вот несколько псевдокодов.
public async void LoadWizard()
{
IsLoading = true;
StartWizard();
var efData = Refresh();
IsLoading = false;
//update values of properties bound to the view
PropertyBoundToView1 = efData.Prop1;
PropertyBoundToView2 = efData.Prop2;
}
public void StartWizard()
{
//do something with data that are not bound to the view
}
public MyData Refresh()
{
return context.Set<MyData>().FirstOrDefault();
}
Вы можете вызвать пустой делегат в диспетчере пользовательского интерфейса с приоритетом, установленным в Render, чтобы пользовательский интерфейс обрабатывал все операции с очередью с равным или более высоким приоритетом, чем Render. (Пользовательский интерфейс перерисовывается на приоритете диспетчера Render)
public async void LoadWizard()
{
IsLoading = true; //Need the UI to update immediately
App.Current.Dispatcher.Invoke((Action)(() => { }), DispatcherPriority.Render);
//Now lets run the rest (This may take a couple seconds)
StartWizard();
Refresh();
}
DispatcherPriority.Background
?