I have a listbox on a form that gets some data from a service that is slow, I mean a whole 500ms slow. That is unacceptable. The data is not very critical so I can load it in the background.

This easy.

vbnet Private Sub LoadList(ByVal id as Integer) Task.Run(Sub() 'Do something slow RaiseEvent TellTheUIWheAreReadyAndThatItHasNewData(ByVal newList as IList(Of CoolThing)) End Sub) End Sub The UI will update when the Task has run.

Of course when the user rapidly goes from one record to the next. It might see some strange things, since tasks will still run one by one. There is actually nothing that says the data will be the correct data, since we are using threads and we don’t know which thread will finish first. Yeah, threading is easy.

So we would need to cancel our previous task if it is still running.

That is easy.

```vbnet Private cts As CancellationTokenSource

    Private Sub LoadList(ByVal id As integer)
        If cts IsNot Nothing Then
            cts.Cancel()
        End If

        cts = New CancellationTokenSource

        Dim token = cts.Token
        Try
           Task.Run(Sub()
               'Do something slow
               token.ThrowIfCancellationRequested()
               RaiseEvent TellTheUIWheAreReadyAndThatItHasNewData(ByVal newList as IList(Of CoolThing))
           End Sub, token)
        Catch ex As OperationCanceledException
           Log.Debug("Operation cancelled")
        End Try
    End Sub```

So I need a CancellationTokenSource which I need for it’s token and I pass that token to the task.

Next time I run that code I will just be default cancel the task, if it is no longer running it won’t matter, And if it is it will cancel before it can inform the UI that it has something new or preferably somewhere before that, you can set that ThrowIfCancellationRequested anywhere you like. Or you could use the IsCancellationRequested from the token and forget about the Try/Catch around it.

Something like this.

```vbnet Private cts As CancellationTokenSource

    Private Sub LoadList(ByVal id As integer)
        If cts IsNot Nothing Then
            cts.Cancel()
        End If

        cts = New CancellationTokenSource

        Dim token = cts.Token
        Task.Run(Sub()
               'Do something slow
               If Not token.IsCancellationRequested() Then
                  RaiseEvent TellTheUIWheAreReadyAndThatItHasNewData(ByVal newList as IList(Of CoolThing))
               End If
        End Sub, token)
    End Sub```

Get it? Good. Let’s move on.