Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLException when Canceling Async Query

Using the new .Net 4.5 Async/Await functionality with a CancellationToken, I get a SQLException when I cancel a ExecuteNonQueryAsync call, instead of a OperationCanceledException (or some other exception that is specific to canceling an operation). The SQLException does say Operation cancelled by user at the end of the message. I expected a more specific exception to be thrown when canceling the operation. Additionally, how would I create the appropriate Try/Catch handlers to deal with this expected scenario? I normally would have the SQLException as more general failure block, but now I would have to tease out the text of the message to see if this just the user clicking the Cancel button!? I must be missing something.

Here's a simple VB WinForm app that has two buttons, one to do the Async call, and the other to cancel. The Try/Catch in the 1st button shows the SQLException that is hit when the 2nd button calls the Cancel method.

Dim _cts As CancellationTokenSource
Private Async Sub btnLocalTest_Click(sender As Object, e As EventArgs) Handles btnLocalTest.Click
    _cts = New CancellationTokenSource()
    Dim CancelToken As CancellationToken = _cts.Token
    Using sconn As New SqlConnection("server=(local);database=MyDB;user id=MyUser;password=MyPassword")
        sconn.Open()
        Dim SQL As String = some long running SELECT or INSERT statement
        Try
            Using scmd As New SqlCommand(SQL, sconn)
                scmd.CommandTimeout = 300
                Dim i As Integer = Await scmd.ExecuteNonQueryAsync(CancelToken)
            End Using
        Catch exCancel As OperationCanceledException
            LogEvent("Query canceled Exception.") ' This error is *not* thrown on Cancel.  
        Catch ex As SqlClient.SqlException
            LogEvent("Error with query. " & ex.Message)  ' This error *is* thrown on Cancel.  Message includes text 'Canceled by user.'
        End Try
        sconn.Close()
        _cts = Nothing
    End Using
End Sub

Private Sub btnLocalTestCancel_Click(sender As Object, e As EventArgs) Handles btnLocalTestCancel.Click
    If _cts IsNot Nothing Then
        _cts.Cancel()
    End If
End Sub

UPDATE: I created a different Async test with the HttpClient.GetAsync method that supports cancellation. When you cancel that task, you can the OperationCanceledException exception that I originally expected above. So the question remains: what exception should you get when you cancel an Async task? Or is that dependent upon each method and it's implementation?

like image 313
Dave Michener Avatar asked Sep 16 '13 20:09

Dave Michener


1 Answers

I "solved" this issue by checking CancelToken.IsCancellationRequested in the Catch ex As SqlClient.SqlException block.

like image 200
Anton S Avatar answered Nov 18 '22 04:11

Anton S