这是对 this question 的后续问题.
我正在尝试从我的数据库加载数据,这将需要 5-10 秒,但我希望 GUI 保持响应,并且它应该是可取消的。
private CancellationTokenSource _source;
public IEnumerable<Measurement> Measurements { get { ... } set { ... } }
private async void LoadData()
{
_source = new CancellationTokenSource();
using (var context = new TraceContext())
{
Measurements = null;
Measurements = await context.Measurements.ToListAsync(_source.Token);
}
}
private void Cancel()
{
if (_source != null)
_source.Cancel();
}
public RelayCommand ReloadCommand
{
get { return _reloadCommand ?? (_reloadCommand = new RelayCommand(Reload)); }
}
private RelayCommand _reloadCommand;
public RelayCommand CancelCommand
{
get { return _cancelCommand ?? (_cancelCommand = new RelayCommand(Cancel)); }
}
private RelayCommand _cancelCommand;
我已经尝试了一些方法,但我无法让它正常工作,这只是加载列表,仅此而已,我无法取消它。
这哪里错了?
最佳答案
感谢您提出这个问题。目前,EF 中此异步 API 的实现依赖于底层 ADO.NET 提供程序来执行取消,但 SqlDataReader.ReadAsync 有一些限制,我们观察到在许多情况下它不会在请求取消时立即取消。我们有a bug我们正在考虑在 EF6 RTM 中进行修复,即在 EF 方法中引入我们自己的行读取取消请求检查。
与此同时,您可以通过使用 ForEachAsync() 将项目添加到列表并检查每一行来解决此限制,例如(未经过彻底测试):
public async static Task<List<T>> MyToListAsync<T>(
this IQueryable<T> source,
CancellationToken token)
{
token.ThrowIfCancellationRequested();
var list = new List<T>();
await source.ForEachAsync(item =>
{
list.Add(item);
token.ThrowIfCancellationRequested();
});
return list;
}
关于c# - 如何以正确的方式取消异步查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18079425/