【发布时间】:2016-01-12 08:05:08
【问题描述】:
我正在开发一个WPF Prism 应用程序。我有一个DelgateCommand,它负责填充一个ObservableCollection,它由UI线程异步拥有using async and await。该集合又被绑定到一个图表。
为了使multiple threads能够访问集合,我启用了synchronization,如下:
BindingOperations.EnableCollectionSynchronization(ChartBoundCollection, _lock);
命令处理逻辑如下:
private async void ShowPatientVisitsVsDays()
{
IsChartBeingPopulated = true;
this.ChartSubTitle = "Requests Vs Days";
this.SeriesTitle = "Days";
ChartBoundCollection.Clear();
await ShowRequestsVsDaysAsync();
IsChartBeingPopulated = false;
}
填充可观察集合的逻辑如下:
private async Task ShowRequestsVsDaysAsync()
{
await Task.Run(() =>
{
if (PatientVisits.Count() > 0)
{
var days = PatientVisits.Select(p => p.VisitDate.Value.Date).Distinct();
foreach (var i in days)
{
var dayVisitCount = PatientVisits.Where(p => p.VisitDate.Value.Date == i).Count();
ChartBoundCollection.Add(new PatientVisitVsXAxis() { XAxis = i.ToShortDateString(), NumberOfPatientVisits = dayVisitCount });
}
}
});
}
我面临的问题是,在设置了 await 的异步方法完成后,我设置 IsChartBeingPopulated = false 的延续没有得到执行。
await ShowRequestsVsDaysAsync();
因此 IsChartBeingPopulated 甚至在异步方法之前设置 完成了。
命令处理程序 ShowPatientVisitsVsDays() 由点击调用 视图上的按钮。该按钮绑定到以下 命令:
ShowPatientVisitsVsDaysCommand = new DelegateCommand(ShowPatientVisitsVsDays);
IsChartBeingPopulated 用于设置属于“扩展 WPF 工具包”的BusyIndiator 控件的IsBusy DependencyProperty。
这个想法是在绑定集合中填充图表数据时显示BusyIndicator。
<xctk:BusyIndicator IsBusy="{Binding Path=IsChartBeingPopulated}" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<chart:ClusteredColumnChart Grid.Row="0" ChartTitle="Patient Visits History" ChartSubTitle="{Binding Path=ChartSubTitle}">
<chart:ClusteredColumnChart.Series>
<chart:ChartSeries SeriesTitle="{Binding Path=SeriesTitle}" DisplayMember="XAxis" ValueMember="NumberOfPatientVisits" ItemsSource="{Binding Path=ChartBoundCollection}" />
</chart:ClusteredColumnChart.Series>
</chart:ClusteredColumnChart>
</Grid>
</xctk:BusyIndicator>
不确定是什么问题。有人知道是什么原因造成的吗?
【问题讨论】:
-
您不应该将
ShowPatientVisitsVsDays类型更改为Task,并等待ShowPatientVisitsVsDays调用,以消除异步状态吗? -
感谢您的评论托马斯。我无法更改 ShowPatientVisitsVsDays 的返回类型,因为它是一个命令处理程序。类似的情况是异步处理按钮的单击事件,在这种情况下,您也无法更改事件处理程序的签名以返回任务。
-
@lovecoding:你想知道,
ShowRequestsVsDaysAsync电话没有等待吗?此外,由于ShowRequestsVsDaysAsync不包含异步代码,因此您应该使其同步并在ShowPatientVisitsVsDays中包装到Task.Run。
标签: c# wpf multithreading asynchronous async-await