Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

Canceling Threads Cooperatively

.NET Framework 4.6 and 4.5

Prior to the .NET Framework 4, the .NET Framework provided no built-in way to cancel a thread cooperatively after it was started. However, in .NET Framework 4, you can use cancellation tokens to cancel threads, just as you can use them to cancel System.Threading.Tasks.Task objects or PLINQ queries. Although the System.Threading.Thread class does not offer built-in support for cancellation tokens, you can pass a token to a thread procedure by using the Thread constructor that takes a ParameterizedThreadStart delegate. The following example demonstrates how to do this.

Imports System.Threading

Public Class ServerClass
   Public Shared Sub StaticMethod(obj As Object)
      Dim ct AS CancellationToken = CType(obj, CancellationToken)
      Console.WriteLine("ServerClass.StaticMethod is running on another thread.")

      ' Simulate work that can be canceled. 
      While Not ct.IsCancellationRequested
         Thread.SpinWait(50000)
      End While
      Console.WriteLine("The worker thread has been canceled. Press any key to exit.")
      Console.ReadKey(True)
   End Sub 
End Class 

Public Class Simple
   Public Shared Sub Main()
      ' The Simple class controls access to the token source. 
      Dim cts As New CancellationTokenSource()

      ' Allow the UI thread to capture the token source, so that it 
      ' can issue the cancel command. 
      Dim t1 As New Thread( Sub()
                               If Console.ReadKey(true).KeyChar = "c"c Then
                                  cts.Cancel()
                               End If 
                            End Sub)

      ' ServerClass sees only the token, not the token source. 
      Dim t2 As New Thread(New ParameterizedThreadStart(AddressOf ServerClass.StaticMethod))

      ' Start the UI thread.
      t1.Start()

      ' Start the worker thread and pass it the token.
      t2.Start(cts.Token)

      t2.Join()
      Console.ReadKey(True)
      cts.Dispose()
   End Sub 
End Class
using System;
using System.Threading;

public class ServerClass
{
   public static void StaticMethod(object obj)
   {
      CancellationToken ct = (CancellationToken)obj;
      Console.WriteLine("ServerClass.StaticMethod is running on another thread.");

      // Simulate work that can be canceled. 
      while (!ct.IsCancellationRequested) {
         Thread.SpinWait(50000);
      }
      Console.WriteLine("The worker thread has been canceled. Press any key to exit.");
      Console.ReadKey(true);
   }
}

public class Simple
{
   public static void Main()
   {
      // The Simple class controls access to the token source.
      CancellationTokenSource cts = new CancellationTokenSource();

      // Allow the UI thread to capture the token source, so that it 
      // can issue the cancel command.
      Thread t1 = new Thread(() => { if (Console.ReadKey(true).KeyChar == 'c')
                                     cts.Cancel(); } );

      // ServerClass sees only the token, not the token source.
      Thread t2 = new Thread(new ParameterizedThreadStart(ServerClass.StaticMethod));

      // Start the UI thread.
      t1.Start();

      // Start the worker thread and pass it the token.
      t2.Start(cts.Token);

      t2.Join();
      Console.ReadKey(true);
      cts.Dispose();
   }
}
Show:
© 2015 Microsoft