How difficult is threading in VB.NET? Not difficult at all if you understand events. For some reason the Threading examples on the net seem a bit more convoluted than they need to be. Here's all you need to know.

First, put a few convenience methods into your long task, as represented by the loop counting down in the below class, LongTask, centered around creating and destroying threads. Note that you'll need to include a module-level ref to your thread (in this case, myThread; not sure why it's Public in my example; that's probably silly).

Public Class LongTask

    Event allDone(ByVal strTemp As String)
    Public myThread As System.Threading.Thread
    Private lngUpperBound As Long = 10000

    Public Sub startMeUp()

        Me.myThread = _
            New System.Threading.Thread(AddressOf Me.countDown)
        Me.lngUpperBound = 99999
        Me.myThread.Start()

    End Sub

    Public Sub countDown()
        Dim i As Long

        For i = Me.lngUpperBound To 1 Step -1
            Console.WriteLine(i)
        Next

        RaiseEvent allDone("Doneige")
    End Sub

    Public Sub killThread()
        Me.myThread.Abort()
    End Sub
End Class


Note how lngUpperBound is changed. This is one method [albeit sloppy] to pass vars to your thread. If you've used VB6 much, you're used to this backdoor passing, for better or for worse.

Because the Thread we created contains a method that raises an event, all we need to do is add an event handler in a parent object to capture when that event is raised -- in other words, add an event handler to listen to the thread's end and we're essentially done.

To do this in a simplest-case fashion, create a Form called Form1 and add three Buttons, Button1, Button2, and Button3. Then slap in this jive:

Public Class Form1
    Inherits System.Windows.Forms.Form

    Public myTask As LongTask

    Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load

        Me.myTask = New LongTask
        AddHandler Me.myTask.allDone, AddressOf Me.showMsg
    End Sub

    Private Sub showMsg(ByVal strMsg As String)
        MsgBox("Form1 message relay: " & strMsg)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

        Me.myTask.startMeUp()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button2.Click

        If Me.BackColor.Equals(System.Drawing.Color.LightSkyBlue) Then
            Me.BackColor = System.Drawing.Color.LightGreen
        Else
            Me.BackColor = System.Drawing.Color.LightSkyBlue
        End If
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button3.Click

        Me.myTask.killThread()
    End Sub
End Class


The end. Button1 starts the thread, Button2 shows that you can perform operations as the thread runs, and Button3 is your cancel button.

So there you have it, how to add multhreading with a cancel button to your VB.NET application.