CancellationToken で新しい .Net 4.5 Async/Await 機能を使用すると、 (または操作のキャンセルに固有のその他の例外)ではなく、呼び出しSQLException
をキャンセルしたときにが返されます。はメッセージの最後に言います。操作をキャンセルするときに、より具体的な例外がスローされることを期待していました。さらに、この予想されるシナリオに対処するには、適切な Try/Catch ハンドラーをどのように作成すればよいでしょうか? 通常は、より一般的な失敗ブロックを使用しますが、メッセージのテキストを取り出して、ユーザーが [キャンセル] ボタンをクリックしただけかどうかを確認する必要があります!? 私は何かが欠けているに違いない。ExecuteNonQueryAsync
OperationCanceledException
SQLException
Operation cancelled by user
SQLException
これは、非同期呼び出しを実行するボタンとキャンセルするボタンの 2 つのボタンを持つ単純な VB WinForm アプリです。1 番目のボタンの Try/Catch はSQLException
、2 番目のボタンが Cancel メソッドを呼び出したときにヒットしたことを示しています。
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
上記で最初に予想した例外が発生する可能性があります。 Async タスクをキャンセルしたときに、どのような例外が発生するのでしょうか? それとも、各メソッドとその実装に依存していますか?