Отмена других запущенных задач, поставленных в очередь в Prism EventAggregator - PullRequest
0 голосов
/ 16 мая 2018

У меня есть приложение WPF, использующее Prism.Когда пользователь выбирает строки из сетки данных, он запускает событие SelectionUpdated в EventAggregator.

Один из моих других ViewModels прослушивает это событие и, когда он его получает, запускает асинхронный процесс для получения некоторых удаленных результатов на основе выбора.Это может занять до 10 секунд.Когда он возвращает результаты, он обновляет ViewModel с результатами, которые затем привязываются к таблице результатов.

Проблема, с которой я столкнулся, заключается в том, что пользователь делает второй выбор во время выполнения первого, т.е. выбирает строки 2-4 затем передумает и вместо этого выбирает строки 2-8, кажется, что EventAggregator является однопоточным каналом, и первое полученное событие должно завершиться полностью, включая асинхронный бит, прежде чем начнется второе.

Iэффективно хотите отменить первый запрос, если второй получен.Мой код позади этого представления - это то, где захватывается событие выбора, и этот код позади публикует событие SelectionUpdated.Поэтому, если EventAggregator является однопоточным, то мне нужно в коде каким-то образом сообщить моей модели представления, которая в данный момент обрабатывает событие SelectionUpdated, отменить и выйти, освободив конвейер EventAggregator subcribe () для обработки второго события.немедленно.

Надеюсь, это имеет смысл.Мой код позади.

Grid.MouseLeftButtonUp += (sender, args) =>
{
    var selectedEntries = Grid.SelectedCells.Select(c => c.Item as EntryViewModel).Where(c => c != null).Distinct().ToArray();
    _eventAggregator.GetEvent<SelectionUpdatedEvent>().Publish(selectedEntries);
};

И прослушивающая ViewModel (только соответствующие строки)

_eventAggregator.GetEvent<SelectionUpdatedEvent>().Subscribe(async x => await UpdateSelectedEntries(x));

private async Task UpdateSelectedEntries(EntryViewModel[] selectedEntries)
{
    _selectedEntries = selectedEntries;
    RaisePropertyChanged(nameof(SelectedText));
    RaisePropertyChanged(nameof(SelectedBreakdown));

    await RecalculateAll();
}

private async Task RecalculateAll()
{
    try
    {
        var entryIds = _selectedEntries.SelectMany(s => s.StatusInfo.ValidEntryIds).OrderBy(t => t).ToArray();
        ProcessingCount++;
        var results = await _resultsService.GetResults(_resultType, entryIds);
...
}

Это последний вызов GetResults, который я хочу прервать, если мой программный код обнаруживаетновый выбор сделан, но я не могу понять, как это сделать.

Есть мысли?

1 Ответ

0 голосов
/ 16 мая 2018

По умолчанию вы подписываетесь на ветку издателя. Вы хотите подписаться на поток пула потоков, чтобы ваши подписки могли работать параллельно.

_eventAggregator.GetEvent<SelectionUpdatedEvent>().Subscribe(async x => await UpdateSelectedEntries(x), ThreadOption.BackgroundThread);

Ваш подписчик отменит CancellationToken, использованный в предыдущем задании, чтобы заменить его своим (очевидно, что эта часть должна быть синхронизирована).

...