Я создаю ObservableCollection объектов ViewModel, где каждый объект имеет несколько задач для завершения, когда он инициализируется.Асинхронно обновлять несколько свойств в списке
Я добавляю их к ObservableCollection, как это в родительском ViewModel:
public async void ButtonPressCommandHandler()
{
for (int i = 0; i < 25; ++i)
{
var testViewModel = new TestViewModel();
await testViewModel.Initialize();
TestViewModels.Add(testViewModel);
}
}
Этот цикл просто вызывается на кнопку мыши или другого события.
А вот код тест ViewModel:
public class TestViewModel : ViewModelBase
{
private string _taskOne;
public string TaskOne
{
[DebuggerStepThrough]
get { return _taskOne; }
set
{
if (value != _taskOne)
{
_taskOne = value;
RaisePropertyChanged(() => TaskOne);
}
}
}
private string _taskTwo;
public string TaskTwo
{
[DebuggerStepThrough]
get { return _taskTwo; }
set
{
if (value != _taskTwo)
{
_taskTwo = value;
RaisePropertyChanged(() => TaskTwo);
}
}
}
public async Task Initialize()
{
TaskOne = await TaskOneAsync();
TaskTwo = await TaskTwoAsync();
}
private Task<string> TaskOneAsync()
{
return Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
return "Task one";
});
}
private Task<string> TaskTwoAsync()
{
return Task.Factory.StartNew(() =>
{
var random = new Random();
int randomNumber = random.Next(500, 5000);
Thread.Sleep(randomNumber);
return "Task two: " + randomNumber;
Thread.Sleep(randomNumber);
return "Task two: " + randomNumber;
});
}
}
(. Я знаю, что могу назвать инициализации работы в конструкторе, но это ближе к тому, что мне действительно нужно сделать)
В моей view, у меня есть ListView
, где ListView.ItemTemplate
просто отображает текстовые блоки с объектами TaskOne
и TaskTwo
. Это ItemSource
обязателен для TestViewModels
.
Что я вижу, так это то, что для каждого из 25 объектов создаются объекты TaskOne
и TaskTwo
одновременно, и каждый объект отображается только после завершения обеих задач.
Если удалить await
из Initialize()
и имеет Initialize()
возвращение пустоты (это в потоке пользовательского интерфейса) поведение лучше- я вижу все TaskOne
свойств очень быстро, а затем TaskTwo
свойства начинают заполнять. Но случайное значения, которые они отображают, неправильны - существует много дубликатов, и они, похоже, заполняют список кусками или 4 или 5 (что трудно сказать).
Вся цель этого в не-тестовом коде заключается в обновлении индикатора прогресса, привязанного к TaskTwo
. Что-то вроде этого (от TestViewModel
кода):
public async Task Initialize()
{
TaskOne = await TaskOneAsync();
Loading = true;
TaskTwo = await TaskTwoAsync();
Loading = false;
}
Где все объекты загрузки сразу в список, а затем асинхронно обновить свои TaskOne
и TaskTwo
свойства, как они завершат, и обновлять индикатор прогресса на основе от работы в TaskTwo
. Но пока не удастся заставить это работать.
EDIT: Добавлен лучший пример кода и объяснения
1. Ваш ViewModel реализует 'INotifyPropertyChanged'? 2. Вам известно, что вы запускаете задачу «async» и не ожидаете приведенной задачи? – i3arnon
2 *. На первый взгляд я вижу, что вы используете 'async void', который настоятельно рекомендуется против (если это не обработчик событий UI) – i3arnon
Не могли бы вы опубликовать короткий, но * полный * код, который демонстрирует проблему? Трудно понять, что происходит из этих нескольких фрагментов. – svick