cancel
Showing results for 
Search instead for 
Did you mean: 

Terminating query using Entity Framework

Former Member
5,378

My program has a search feature. There is a cancel button that is displayed on the window when the user starts a search. If the search is taking longer than they want to wait for it to complete, they can click this button and it stops the query.

My program uses an Entity Framework 4 data model to query the database. I have a method in my data access layer which returns an instance of the entity model context class as an IDisposable. This same object is then used to build the IQueryable that is used for the search. It's after the IQueryable has been converted into a SQL query and while that query is executing that the user will click on the cancel button.

When the user clicks on the Cancel button, the following code is executed:

private void CancelButton_Click( object sender, RoutedEventArgs e ) {
    if ( Connection != null ) {
        CancelButton.IsEnabled = false;
        Task.Factory.StartNew( () => {
            lock ( ConnectionLock ) {
            tryagain:
                try {
                    Connection.Dispose();
                } catch ( Exception ex ) {
                    Log.Error( "An error occurred while canceling a search: " + ex.ToString() );
                    goto tryagain;
                }
                Connection = null;
                Dispatcher.Invoke( new Action( () => {
                    CancelButton.IsEnabled = true;
                } ) );
            }
        } );
    }
    e.Handled = true;
}

Sometimes, the call to Connection.Dispose() returns quickly. Sometimes, it take a while for it to return. Sometimes it throws the following error:

System.Data.EntityException was caught
  HResult=-2146233087
  Message=An error occurred while closing the provider connection. See the inner exception for details.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.EntityClient.EntityConnection.StoreCloseHelper()
       at System.Data.EntityClient.EntityConnection.Dispose(Boolean disposing)
       at System.ComponentModel.Component.Dispose()
       at System.Data.Objects.ObjectContext.Dispose(Boolean disposing)
       at System.Data.Objects.ObjectContext.Dispose()
       at CarSystem.CustomControls.PageSelector.<CancelButton_Click>b__5() in c:\\ElsagTFS\\EOC4\\Client UI-chile\\CustomControls\\PageSelector.xaml.cs:line 746
  InnerException: iAnywhere.Data.SQLAnywhere.SAException
       HResult=-2147467259
       Message=Communication error
       Source=SQL Anywhere .NET Data Provider
       ErrorCode=-2147467259
       NativeError=-85
       StackTrace:
            at iAnywhere.Data.SQLAnywhere.SAInternalConnection.CheckException(Int32 idEx, Boolean freeConn)
            at iAnywhere.Data.SQLAnywhere.SAInternalConnection.ReturnToPool()
            at iAnywhere.Data.SQLAnywhere.SAConnectionPool.ReturnConnection(SAInternalConnection connection)
            at iAnywhere.Data.SQLAnywhere.SAConnectionPoolManager.ReturnConnection(SAInternalConnection connection)
            at iAnywhere.Data.SQLAnywhere.SAConnection.Dispose(Boolean disposing)
            at iAnywhere.Data.SQLAnywhere.SAConnection.Close()
            at System.Data.EntityClient.EntityConnection.StoreCloseHelper()

In my testing, trying the call to Connection.Dispose() after receiving the exception succeeds.

My question is what does this exception mean? Why is it taking so long for the query to stop running sometimes? Is my method for dealing with it OK? Is there anything I'm missing or should be doing?

jeff_albion
Advisor
Advisor

Hi Tony,

The -85 "Communication Error" error specifically means that the connection was 'already' disconnected when we went to .Close() and return the connection to the connection pool, and we propagated the exception back up to the calling application.


Do you have a way of reproducing this behaviour if you repeatedly start and cancel queries via code or a GUI application? If so, could you provide that reproducible to us? If not, do you have a console log from the database server from when this happens to determine if client connections are being kicked off from the server side prior to the .Dispose() call?

Former Member
0 Kudos

Jeff: Sorry I didn't get back to you sooner. I'll try to put together something to reproduce the problem next week. I'm afraid I don't have a server console log.

Accepted Solutions (0)

Answers (0)