我有一个使用Prism的WPF应用程序。当用户从数据集中选择行时,它会在SelectionUpdated上触发一个EventAggregator事件。
我的另一个ViewModels正在监听该事件,当它接收到该事件时,启动一个异步进程,根据所选内容检索一些远程结果。这需要10秒的时间。当它得到结果时,它用结果更新ViewModel,然后将结果绑定到结果网格。
我遇到的问题是,如果用户在运行第二次选择时,即选择2-4行,然后改变主意,选择第2-8行,那么EventAggregator似乎是一个单线程管道,第一个接收到的事件必须在第二个线程开始之前完全完成,包括异步比特。
如果收到第二个请求,我实际上想要一种取消第一个请求的方法。视图的代码隐藏是捕获选择事件的地方,然后这个代码隐藏发布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的最后一次调用,如果我的代码隐藏检测到新的选择已经完成,我想中断它,但是我想不出如何做到这一点。
有什么想法吗?
发布于 2018-05-16 19:27:34
默认情况下,您在publisher线程上订阅。您希望在线程池线程上订阅,以便您的订阅可以并行运行。
_eventAggregator.GetEvent<SelectionUpdatedEvent>().Subscribe(async x => await UpdateSelectedEntries(x), ThreadOption.BackgroundThread);然后,您的订阅者将取消先前任务所使用的CancellationToken,将其替换为自己的任务(这部分显然必须同步)。
https://stackoverflow.com/questions/50375144
复制相似问题