Q:

How do I stop/cancel a task processing a function or find a better way of doing this?

I have ...
Private Sub TestTask()
    Debug.Write("Running")

    For i As Integer = 0 To 60
        Debug.Write(".")
        System.Threading.Thread.Sleep(1000)
    Next

    Debug.WriteLine("Finished")
End Sub

....
Dim cts As New CancellationTokenSource
Dim oToken As CancellationToken = cts.Token

'Create HelperTask to wait for cancellation request
Dim oHelperTask As Task = Task.Factory.StartNew(Function()

        'Create Task to invoke function
        Dim oTask As Task = Task.Factory.StartNew(Function()
            Return outerFunction.Invoke
        End Function, oToken)

        ' wait for cancellation token if Task is not complete
        While oTask.Status = TaskStatus.Running
            Thread.Sleep(200)
            If oToken.IsCancellationRequested Then
                oToken.ThrowIfCancellationRequested()
                Return Nothing
            End If
        End While

        Return oTask.Result

End Function, oToken)

cts.cancel()

But in my debug window on visual sudio my TestTask() continues to run with ..... please anyone enlighten me. Thanks

A:

You don't want/need 2 tasks - it's cooperative cancellation, so every task you want to end when cancel is called will need to include ThrowIfCancellationRequested (or however it should handle cancellation).  There's intentionally no Thread.Abort type behavior/semantics, it's all cooperative.

A:

The whole point of the CancellationToken is that the actual worker lambda (or function) should check it to see if it should stop. In your case, TestTask must have access to the token and check it after each iteration. Neither the multiple helper tasks or the checks for the task status or the cancellation request check are necessary.
The MSDN article on Task Cancelation shows how the only thing required is for the lambda to check the token, nothing more.
In your case, TestTask can respond to a cancellation with code as simple as this:
Sub Main()
    Dim cts As New CancellationTokenSource
    Dim token = cts.Token

    Task.Factory.StartNew(Sub() TestTask(token), token)

    Thread.Sleep(3000)
    cts.Cancel()
    Console.ReadKey()
End Sub

Private Sub TestTask(token As CancellationToken)
    Console.Write("Running")

    For i As Integer = 0 To 60

        token.ThrowIfCancellationRequested()

        Console.Write(".")
        Thread.Sleep(1000)
    Next

    Console.WriteLine("Finished")
End Sub

The only thing needed is to pass the token to TestTask and start it like this:
        Task.Factory.StartNew(Sub() TestTask(token), token)

