У меня есть запрос, который требует много времени для возврата, поэтому я вставляю функцию с возвратом данных в функцию внутри задачи, например, так:
Dim tokenSource As CancellationTokenSource
Private Async Sub btnSomeThing() Handles btnSomething.Click
tokenSource = New CancellationTokenSource
Dim cancellationToken As CancellationToken = tokenSource.Token
Dim t As Task(Of DataTable) = Task.Run(Function()
Return someFunction.GetDataTable()
End Function,
cancellationToken)
Await t
Try
If t.Result.Rows.Count > 0 Then
' Display the datatable
End If
Catch e As Exception
If TypeOf e IsNot TaskCanceledException Then
MessageBox.Show("Error")
End If
Finally
tokenSource.Dispose()
End Try
End Sub
И я пытаюсь отменить задачу с помощьювызов tokenSource.Cancel()
в другом месте.
Однако, что я вижу, это то, что когда Return someFunction.GetDataTable()
в конечном итоге возвращается, код продолжает выполняться, как будто эта задача не была отменена.
Я понимаю,что someFunction.GetDataTable()
будет продолжаться до тех пор, пока это не будет сделано, поскольку нет хорошего способа остановить вызов базы данных после его запуска, но когда он все-таки возвращает, не должно вызывать задачу t
выдает TaskCanceledException, и поэтому остальная часть процедуры пропускается какчасть Try-Catch?
Как правильно отменить t
?
РЕДАКТИРОВАТЬ:
Ниже приведен код сейчас.Исключение из cancellationToken.ThrowIfCancellationRequested()
не «перехватывается», и поэтому приложение просто вводит режим останова.Я также пытался дозвониться до cancellationToken.ThrowIfCancellationRequested()
в течение Task.Run
, после Await t
, но все они имеют одинаковый эффект.После вызова cancellationToken.ThrowIfCancellationRequested()
приложение вылетает.
Dim tokenSource As CancellationTokenSource
Private Async Sub btnSomeThing() Handles btnSomething.Click
tokenSource = New CancellationTokenSource
Dim cancellationToken As CancellationToken = tokenSource.Token
Dim t As Task(Of DataTable) = Task.Run(Function()
Return GetDataTable(cancellationToken)
End Function,
Try cancellationToken)
Await t
If t.Result.Rows.Count > 0 Then
' Display the datatable
End If
Catch ex As AggregateException
For Each item In ex.InnerExceptions
Debug.WriteLine(ex.Message & " " & item.Message)
Next
Finally
tokenSource.Dispose()
End Try
End Sub
Public Function GetDataTable (cancellationToken As CancellationToken)
Dim dt As DataTable
'fill dt from query with DataAdapter
cancellationToken.ThrowIfCancellationRequested()
Return dt
End Function