我有一个使用Prism的WPF应用程序。当用户从数据网格中选择行时,它会在EventAggregator上触发SelectionUpdated事件。
我的其他一个ViewModel正在监听该事件,当它收到它时,启动异步过程以根据选择检索一些远程结果。这可能需要10秒钟。当它返回结果时,它会使用结果更新ViewModel,然后将结果绑定到结果网格。
我遇到的问题是,如果用户在第一次选择时进行第二次选择,即选择第2-4行然后改变主意并选择第2-8行,则看起来EventAggregator是单线程管道而第一个收到的事件必须在第二个开始之前完全完成,包括异步位。
如果收到第二个请求,我实际上想要一种取消第一个请求的方法。我对视图的代码隐藏是捕获选择事件的地方,然后这个代码隐藏发布SelectionUpdated事件。因此,如果EventAggregator只是单线程,那么我需要在代码隐藏中使用某种方式告诉我当前处理SelectionUpdated事件的viewmodel,取消并退出,释放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的最后一次调用,如果我的代码隐藏已经检测到新的选择,我想要中断,但我无法弄清楚如何执行此操作。
有什么想法吗?
答案 0 :(得分:0)
默认情况下,您订阅发布商线程。您希望订阅线程池线程,以便您的订阅可以并行运行。
_eventAggregator.GetEvent<SelectionUpdatedEvent>().Subscribe(async x => await UpdateSelectedEntries(x), ThreadOption.BackgroundThread);
然后,您的订阅者将取消上一个任务使用的CancellationToken
,将其替换为自己的(此部分显然必须同步)。