2016-11-02 8 views
1

У меня есть приложение WPF, использующее свойство MVVM design. Существует долгий процесс заполнения сетки, для которой я хотел бы показать загруженный курсор. У меня есть часть, меняющая курсор. Проблема в том, что курсор связан с bool под названием IsBusy. Когда вызывается метод, который выполняется некоторое время, я устанавливаю IsBusy в true, и когда метод будет завершен, я верну его к false.WPF MVVM Refresh View

public void LongProcedure(){ IsBusy=true; ... long running code here IsBusy=false; } `

Я знаю, что курсор привязки к IsBusy работает, потому что я проверил это с другой процедурой, которая делает

IsBusy=!IsBusy; 

И что делает переключение курсора. Проблема, с которой я сталкиваюсь, заключается в том, что представление не обновляется, пока код в методе запущен. Есть ли способ заставить представление refesh после того, как я установил IsBusy в true?

+0

Выполняете ли вы длительную задачу в той же теме? – XAMlMAX

+0

Да, я надеялся сохранить это просто. Процесс занимает от 5 до 10 секунд, и они не могут ничего сделать во время работы. Я хотел показать курсор ожидания, чтобы пользователь знал, что что-то происходит. – Pedler

+0

@Pedler К сожалению, этот же поток необходим для обновления экрана. Когда он запускает что-то еще, его нельзя использовать для обновления экрана. – Aron

ответ

3

В каждом оконном приложении есть один поток, предназначенный для работы с визуальным представлением приложения. Этот поток the UI thread. Когда ваш код запускается в ответ на событие окна (например, событие Loaded или пользователь, нажимая на кнопку), он работает в этом потоке пользовательского интерфейса. Пока выполняется ваш код, поток пользовательского интерфейса занят выполнением вашей работы и не может обновлять визуальное представление окна. В крайних случаях (т. Е. Ваша работа требует заметного количества времени для завершения), ваше окно будет заблокировано.

Если вы выполняете длительную работу с использованием потока пользовательского интерфейса, то вы не делаете это правильно. Вы должны либо использовать async-wait, либо использовать Task.Run(), чтобы выполнить свою работу на фоновом потоке.

Если LongProcedure() является IO-привязанным (например, ожиданием данных откуда-то), вы должны использовать async-wait. Если CPU переплете (много обработки данных/расчетов), то вы должны использовать Task.Run()

Асинхронный-Await:

public async Task LongProcedure() 
{ 
    IsBusy = true; 

    await GetDataFromSomewhereAsync(); 

    IsBusy = false; 
} 

public async void CallingMethod() 
{ 
    ...... 
    await LongProcedure(); 
} 

Task.Run:

public void LongProcedure() 
{ 
    IsBusy = true; 
    ... // long running code here 
    IsBusy = false; 
} 
public async void CallingMethod() 
{ 
    ...... 
    await Task.Run((Action) LongProcedure); 
} 

Пожалуйста, обратите внимание, что пользовательский интерфейс не может быть обновлен непосредственно из фонового потока. Как правило, вам необходимо указать маршал ваш код обновления на поток пользовательского интерфейса. Существует несколько способов сделать это, и это зависит от того, какое приложение для Windows вы используете, например windows forms, WPF и т. Д.

+0

Спасибо за помощь. Это указывало на правильное направление. Я закончил использование класса BackgroundWorker. – Pedler