这是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;
我已经尝试了一些事情,但是我无法让它正常工作,这只是加载了List而这就是全部,我无法取消它。
这个错误在哪里?
答案 0 :(得分:4)
感谢你提出这个问题。目前,EF中此异步API的实现依赖于底层ADO.NET提供程序来取消,但SqlDataReader.ReadAsync有一些限制,我们观察到在许多情况下,在请求取消时不会立即取消。我们正在考虑修复EF6 RTM中的a bug,这是关于在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;
}