none
entity framework cancel long running query RRS feed

  • Question

  • 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();
            }

    Tuesday, October 9, 2012 1:23 PM

Answers

  • Hi,

    In EF 6, the next version of EF that hasn't been released yet, there are a bunch of Async methods. Such as ToListAsync which accepts a cancelation token.

    There is no way in EF 5 or lower to be able to pass a cancelation token to do what you want.

    You can, of course, work around it in various ways. But you will still end up executing a synchronous query in the middle and either discarding or keeping the result.

    You can see the async support in EF, and try it out if you like, by getting the latest nightly build and looking at documentation on codeplex:

    http://entityframework.codeplex.com/wikipage?title=specs 

    http://entityframework.codeplex.com/wikipage?title=Nightly%20Builds


    We are seeing a lot of great Entity Framework questions (and answers) from the community on Stack Overflow. As a result, our team is going to spend more time reading and answering questions posted on Stack Overflow. We would encourage you to post questions on Stack Overflow using the entity-framework tag. We will also continue to monitor the Entity Framework forum.

    Tuesday, October 9, 2012 8:15 PM
    Moderator