This appears to be a common problem but I am unable to find a solution yet. I have checked this in SO Cancelling a Task is throwing an exception
My caller:
Private Async Sub btnTestTimer_Click(sender As Object, e As EventArgs) Handles btnTest.Click
_cts = New CancellationTokenSource()
Try
Await Task.Run(AddressOf TestCancellationAsync).ConfigureAwait(False)
Catch cx As OperationCanceledException
MsgBox(String.Format("The following error occurred: {0}", cx.Message), MsgBoxStyle.Critical)
Catch ex As Exception
MsgBox(String.Format("The following error occurred: {0}", ex.Message), MsgBoxStyle.Critical)
End Try
End Sub
My task is here
Private Async Function TestCancellationAsync() As Task
'Launch a dummy timer which after some time will itself cancel a token and throw
Dim tmr As New System.Timers.Timer(1000)
AddHandler tmr.Elapsed, AddressOf OnTimerElapsed
tmr.Enabled = True
End Function
And the timer function that cancels and throws out is
Private Sub OnTimerElapsed(sender As Object, e As ElapsedEventArgs)
Dim tmr As System.Timers.Timer = CType(sender, System.Timers.Timer)
tmr.Enabled = False
Task.Delay(5000) 'After 5 seconds simulate a cancellation
_cts.Cancel() //This is just to cancel from within the timer, actually the cancellation to _cts will happen from another caller which is not shown here
_cts.Token.ThrowIfCancellationRequested()
End Sub
The actual program with the async task and the cancellation is not shown here to keep the example concise while still being able to replicating the problem.
The business requirement is that on clicking a button, an asynchronous task will be launched, which will open up several async functions. One of them would launch a timer which will keep checking the _cts token state and cancel if required. If such a cancellation happens from outside on the _cts token the timer will throw a cancellation exception
Things I have tried:
- I have handled the OperationCancelled exception but still its not going there.
- I have unchecked Tools-Options-Debug-General-Enable just my code to see if its just Visual Studio. But still it is reported as a PDB unhandled exception
- I have run the exe from outside, as expected, it crashed due to the unhandled exception
Do let me know what I am doing here wrong. My caller awaits for the task to finish - since a timer is running from inside the task, I will expect that the task is not finished and any exceptions raised would be caught.