如何取消一个异步查询的正确方法 [英] How to cancel an async query the right way

查看:183
本文介绍了如何取消一个异步查询的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个后续问题<一href="http://stackoverflow.com/questions/18059275/ef-5-how-to-cancel-a-longrunning-query-in-a-async-task">this问题。

我试图加载从我的数据库中的数据,这将需要5-10秒,但我想在GUI留响应,也应该取消的。

I'm trying to load data from my database which will take 5-10 seconds, but I want the GUI to stay responsive and also it should be cancellable.

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;

我已经尝试了一些东西,但我不能得到这个正常工作,这只是加载列表和多数民众赞成,我无法取消这一点。

I've tried a few things, but I just can't get this to work properly, this just loads the List and thats all, I can't cancel this.

在哪里是错误的呢?

推荐答案

感谢您提出这个问题。目前在EF此异步API的实现依赖于底层的ADO.NET提供兑现消除,但SqlDataReader.ReadAsync有一定的局限性,我们已经观察到,在许多情况下,它不会立即当取消请求取消。我们必须错误,我们正在考虑在固定EF6 RTM是关于介绍我们自己检查行之间的取消请求读取里面的EF方法。

Thanks for bringing this up. Currently the implementation of this async API in EF relies on the underlying ADO.NET provider to honor cancellation, but SqlDataReader.ReadAsync has some limitations and we have observed that in many cases it won't cancel immediately when cancellation is requested. We have a bug that we are considering for fixing in EF6 RTM that is about introducing our own checks for the cancellation requests between row reads inside the EF methods.

在此期间,您可以通过使用ForEachAsync()将项目添加到列表中,并检查每一行上,比如此限制(未彻底测试):

In the meanwhile you can workaround this limitation by using ForEachAsync() to add items to the list and check on every row, e.g. (not thoroughly tested):

    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;
    }

这篇关于如何取消一个异步查询的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆