entity framework cancel long running query

2019-02-15 05:18发布

问题:

I am new to the TPL. I am using the TPL to make some async calls to the database. Below the GetDocumentAsync method is called multiple times and do a good job at offloading the task on a different thread to keep the UI thread responsive.

There are two objectives here: 1) Keep the UI Thread Responsive 2) Give the user the ability to abort the request.

I have managed to abort the request however i am unable to abort the request that Entity framework has already put to the database and the query is running at the db level.. or perhaps it has not even started.

Therefore the GetDocuments method still returns the documents on the canceled tasks.

Is there a away i can abort the request from the EF?? Can i do anything better in my implementation ??

    Entities _context = new Entities();

    CancellationTokenSource _tokenSource = new CancellationTokenSource();

    public async void GetDocumentsAsync(string userName)
    {
        IList<Document> results;
        try
        {
            results = await 
            Task<List<Document>>.Factory.StartNew(() =>
            {
                _tokenSource.Token.ThrowIfCancellationRequested();
                return GetDocuments(userName);
            }, _tokenSource);

        }
        catch (OperationCanceledException ex)
        {
            Debug.WriteLine(string.Format("Task canceled for user {0} on thread", userName ));
        }

        if(!_tokenSource.IsCancellationRequested)
        {
            // results is used to update the UI 
        }
    }

    public void Abort()
    {
        _tokenSource.Cancel();
    }

    public List<Document> GetDocuments(string userName)
    {
        //I am using the connected model and need to use the Context for change tracking and other goodies..
        var query = from c in _context.Documents
                    where c.CreatedBy == userName
                    select c;

        query = query.Take(50); // I want to be able to cancel this query. Can this be done ???

        return query.ToList();
    }

回答1:

Async support is part of the upcoming EF6.

Check out KSA's related blog post for an overview.

http://odetocode.com/Blogs/scott/archive/2012/08/26/async-in-entity-framework-6-0.aspx

With that, you'll switch to ToListAsync with a cancellation token.

http://entityframework.codeplex.com/SourceControl/changeset/view/fe17fe748307#src%2fEntityFramework%2fIQueryableExtensions.cs