使用带有 CancellationToken 的新 .Net 4.5 Async/Await 功能,当我取消 SQLException 调用时得到 ExecuteNonQueryAsync,而不是 OperationCanceledException(或某些其他特定的异常取消操作)。 SQLException 确实在消息末尾说 Operation cancelled by user。我预计在取消操作时会抛出更具体的异常。此外,我将如何创建适当的 Try/Catch 处理程序来处理这种预期的情况?我通常会将 SQLException 作为更一般的故障块,但现在我必须梳理消息的文本以查看这是否只是用户单击“取消”按钮!?我肯定错过了什么。

这是一个简单的 VB WinForm 应用程序,它有两个按钮,一个用于执行异步调用,另一个用于取消。第一个按钮中的 Try/Catch 显示了当第二个按钮调用 Cancel 方法时命中的 SQLException

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

更新: 我使用支持取消的 HttpClient.GetAsync 方法创建了一个不同的异步测试。当您取消该任务时,您可以出现我在上面最初预期的 OperationCanceledException 异常。所以问题仍然存在:取消异步任务时应该得到什么异常?或者这取决于每种方法及其实现?

最佳答案

我通过检查 CancelToken.IsCancellationRequested 块中的 Catch ex As SqlClient.SqlException 来“解决”了这个问题。

关于.net - 取消异步查询时出现 SQLException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18836869/

10-17 01:48