Here's a (silly) example of a method that blocks the caller's thread but does not support cancellation:
Public Sub WorkUntil5()
Threading.SpinWait.SpinUntil(Function() Now.Hour >= 17)
End Sub
In the worst case scenario, calling this method takes 17 hours to return. Pretend that I don't have access to the source code of this method. How do I wrap the call in a method that takes a CancellationToken?
The goal is to let WorkUntil5()
run until cancellation is requested. At that point the call should be terminated using any means possible.
Here's the best way I could come up with myself. It uses tasks, but it still blocks the caller's thread. Something about that doesn't feel right. Thinking there should be a better way to call mres.Set()
once the first call returns.
Public Sub WorkUntilYouGetBored(cancellationToken As Threading.CancellationToken)
Dim mres As New Threading.ManualResetEventSlim
Using cancellationToken.Register(Sub() mres.Set())
Dim t = Task.Factory.StartNew(Sub() WorkUntil5())
t.ContinueWith(Sub() mres.Set())
mres.Wait()
End Using
If cancellationToken.IsCancellationRequested Then
Console.WriteLine("You went home early.")
Else
Console.WriteLine("It's time to go home.")
End If
End Sub
See Question&Answers more detail:os