我是.net中的异步处理的新手(老实说,根本就是.net)并需要以下问题的帮助。
为了实现这一点,我需要知道如何处理同步方法的多个调用。
我得到了以下C#MVVM应用程序:
两个Datagrids都绑定到Viewmodel。第一个Datagrid是第二个的输入。每次单击第一个Datagrid中的复选框时,都会触发DelegateCommand,以刷新第二个数据网格的内容。
刷新工作就像在这个例子中一样:
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Path=Datagrid1}" >
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Boolean, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Command="{Binding DataContext.CheckBoxDataGrid1Click, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
ObservableCollection<string> col1 = ObservableCollection<string>();
ObservableCollection<string> col2 = ObservableCollection<string>();
DelegateCommand CheckBoxDataGrid1Click = new DelegateCommand(CheckBoxDataGrid1ClickExecute);
// Needs to be async, so that the UI thread is will not be freezed.
private async void CheckBoxDataGrid1ClickExecute()
{
var ui = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Factory.StartNew(
() =>
{
return getNewObjects();
}).ContinueWith(t =>
{
col2 = t.Result;
}, ui);
}
[MethodImpl(MethodImplOptions.Synchronized)]
public ObservableCollection<string> getNewObjects()
{
// Here is a long processing SQL Query
// So lets wait a few seconds
Thread.Sleep(5000);
// return dummy in this example
return new ObservableCollection<string>();
}
我遇到问题,如果有人点击了一个复选框(在Datagrid1中),那么最后一次点击的处理还没有完成。
我的第一个想法是使getNewObjects()方法同步。这解决了一些问题。但是,多次点击会导致现在的茶点队列。一方面我不知道呼叫的顺序。另一方面,我只对最后一次点击的结果感兴趣。
第二个想法是修改getNewObjects()方法,以便CancellationToken可以取消它。 (我已在这里开始提问 - C# Synchronized Method call kills current processing)。这种方式也不起作用。该方法包含一个SQL查询,在这种情况下无法轻松取消。我无法修改查询或SqlCommand的执行。
总结: 有没有办法丢弃当前的茶点处理并开始新的处理?如果没有,我该如何处理呼叫队列?我需要确保,最后一次调用将是第二个Datagrid的内容,即使稍后有另一个完成。
我愿意接受任何解决这个问题的建议。每当Datagrid 1发生变化时,也许有更好的方法来刷新第二个Datagrid。