【发布时间】:2019-08-20 06:59:56
【问题描述】:
我开始学习在 VB.NET 中运行可取消 SQL 查询的异步/任务函数。
我在一个类库中有以下代码,它运行两个任务并且没有任何异常处理,因为我想在调用类库的应用程序中处理这个。我在类库中有以下代码。
Public Async Function DirectoryList(ct As CancellationToken) As Task(Of List(Of Directory))
ct.ThrowIfCancellationRequested()
Dim ds As DataSet
Dim dirs As List(Of Directory)
Dim ctUnregister As CancellationTokenRegistration
ds = Await Task.Run(Function()
Using newConnection = New SqlConnection(Me.InitializationData.ConnectionString)
Using sqlAdapter = New SqlDataAdapter("DirectoryList", newConnection)
ctUnregister = ct.Register(Sub() sqlAdapter.SelectCommand.Cancel())
With sqlAdapter
.SelectCommand.CommandType = CommandType.StoredProcedure
.SelectCommand.CommandTimeout = Me.InitializationData.CommandTimeout
End With
Dim newDataSet As DataSet = New DataSet()
sqlAdapter.Fill(newDataSet)
Return newDataSet
End Using
End Using
' Remove the registration we set earlier so the cancellation token can be used normally.
ctUnregister.Dispose()
End Function, ct)
dirs = Await Task.Run(Function()
Dim dirsResult As New List(Of Directory)
Dim tbl As DataTable = ds.Tables(0)
For Each row As DataRow In tbl.Select()
' process the data
ct.ThrowIfCancellationRequested()
Next
Return dirsResult
End Function, ct)
Return dirs
End Function
然后我这样称呼它:
Try
dirs = Await databaseLibrary.DirectoryList(cts.Token)
MsgBox("Query complete!")
Catch ex As System.Data.SqlClient.SqlException
MsgBox("Cancelled (SQL)")
Catch ex2 As OperationCanceledException
MsgBox("Cancelled")
Catch ex3 As Exception
MsgBox("Cancelled")
End Try
从功能上看,它似乎按预期工作 - 我可以取消请求并按预期抛出异常。
但是我想处理异常,以便我可以优雅地取消任务,但是即使在 IDE 中以调试模式运行时,应用程序仍然会中断并且异常(例如 SqlException)会显示在 IDE 中。如果我踩下去,最终 Catch 逻辑就会运行。
当应用程序在 IDE 之外运行时,异常处理会按预期工作。
这似乎与在调试器中运行时的正常行为不同 - 通常异常处理会运行,但只有在未处理异常时才会中断。
为什么这种行为不同,大概是因为异步函数?
【问题讨论】:
-
然后返回一个你可以处理的任务……
标签: vb.net exception async-await