如何以正確的方式取消異步查詢

.net c# entity-framework entity-framework-6 wpf

這是對這個問題的後續問題

我正在嘗試從我的數據庫加載數據,這需要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而且那就是全部,我無法取消它。

這個錯誤在哪裡?

一般承認的答案

謝謝你提出這個問題。目前,EF中此異步API的實現依賴於底層ADO.NET提供程序來取消,但SqlDataReader.ReadAsync有一些限制,我們觀察到在許多情況下,在請求取消時不會立即取消。我們正在考慮修復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;
    }



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因