Using ThreadPools in Windows Applications


Developers frequently need to perform tasks in their applications that are not instantaneous.

To support such scenarios, Windows developers can use thread pools to execute work in parallel threads that execute asynchronously from the main thread. A thread pool can be considered as a work manager that has a bunch of worker threads. The ThreadPool class assigns work in a queue fashion. As soon as a thread completes a task, it becomes available and ThreadPool picks up the next work item from the queue to execute. This prevent blocking the UI thread, which is a very important part of the user experience.

In addition, thread pools can be used to control the priority of work items and even remove them from the queue. Work items can be scheduled to use timers and periodic timers. For critical work items, ThreadPool can be used to allocate specific resources that ensure that these tasks do not starve for cycle time. Finally, thread pools support running work items in response to named events and semaphores.

Because thread pools run at the OS level, they are more efficient than user-initiated thread management.

Hands On

For our demo, we will create a simple Windows application that exercises common scenarios involving ThreadPool.

Create a new Visual Studio 2013 project using the Blank App (Windows) template.

Figure 1: Creating a new project

Add a new control to the default XAML page of the application, MainPage, as shown below.

Figure 2: Adding controls

The XAML for the above controls looks like this:


   <Grid Background="{ThemeResource
      <Button x:Name="buttonScenario1SubmitWorkItemToThreadPool"
         Content="Submit work item to threadpool"
         HorizontalAlignment="Left" Margin="718,107,0,0"
         VerticalAlignment="Top" Width="383" />
      <TextBlock HorizontalAlignment="Left" Margin="335,122,0,0"
         TextWrapping="Wrap" Text="Scenario 1 - Submit a work item"
      <TextBox x:Name="textBoxDesiredPrimeNumberLocation"
         HorizontalAlignment="Left" Margin="574,110,0,0"
         Text="1000" VerticalAlignment="Top" InputScope="Number"/>
      <TextBox x:Name="textBoxStatus" HorizontalAlignment="Left"
         Margin="658,513,0,0" TextWrapping="Wrap" Text="Status"
         VerticalAlignment="Top" Width="469"/>
      <TextBlock HorizontalAlignment="Left"
         Margin="335,207,0,0" TextWrapping="Wrap"
         Text="Scenario 2 - Submit workitem using timer"
      <TextBox x:Name="textBoxTimer" HorizontalAlignment="Left"
         Margin="574,207,0,0" TextWrapping="Wrap" Text="1000"
         VerticalAlignment="Top" InputScope="Number"/>
      <Button x:Name="buttonScenario2SubmitWorkitemUsingTimer"
         Content="Submit work item using timer"
         HorizontalAlignment="Left" Margin="721,192,0,0"
         VerticalAlignment="Top" Width="380" />
      <TextBlock HorizontalAlignment="Left" Margin="282,307,0,0"
         Text="Scenario 3 - Submit workitem using periodic timer"
      <TextBox x:Name="textBoxPeriodicTimer"
         HorizontalAlignment="Left" Margin="574,291,0,0"
         TextWrapping="Wrap" Text="1" VerticalAlignment="Top"
      <Button x:Name="buttonScenario3SubmitWorkitemUsingPeriodicTimer"
         Content="Submit work item using periodic timer"
         HorizontalAlignment="Left" Margin="721,285,0,0"
         VerticalAlignment="Top" Width="380" />


Next, we will implement using ThreadPool by using various approaches. In the first approach, we will add a workitem to the thread pool for async execution. We will do this via the click event handler for Button for Scenario 1, called "Submit Work Item to Threadpool".

But first, we need to add a variable of type IAsyncAction to the class.

public sealed partial class MainPage : Page
   private IAsyncAction m_workItem;
   public MainPage()

Next, we implement the click event handler for Scenario 1. In this method, we call the ThreadPool.RunAsync method and pass it the logic to execute in the async task. In this method, we also provide the command to update the UI when the task is completed.

private void buttonScenario1SubmitWorkItemToThreadPool_Click
   (object sender, RoutedEventArgs e)
   ulong desiredPrimeNumberLocation =
   ulong nthPrime = 0;
   IAsyncAction asyncAction =
      (workItem) =>
         uint primes = 0;    // Number of primes found so far.
         ulong i = 2;        // Number iterator.

         if ((desiredPrimeNumberLocation >= 0) &&
         (desiredPrimeNumberLocation <= 2))
            nthPrime = desiredPrimeNumberLocation;
         // lame prime number detection logic
         while (primes < (desiredPrimeNumberLocation - 1))
            // Check for prime.
            bool prime = true;
            for (uint j = 2; j < i; ++j)
               if ((i % j) == 0)
                  prime = false;

            if (prime)

         // Return the nth prime number.
         nthPrime = i;

   m_workItem = asyncAction;

   // logic to print the result when the task is complete
   asyncAction.Completed = new AsyncActionCompletedHandler(
      (IAsyncAction asyncInfo, AsyncStatus asyncStatus) =>

         String status = "\n" + "The " + desiredPrimeNumberLocation
            + "th prime number is "
            + nthPrime + ".\n";

         // Update the UI thread with the CoreDispatcher.
            new DispatchedHandler(() =>
                textBoxStatus.Text = status;

ThreadPool can also be used by creating work items using timers. This can be done by using the ThreadPoolTimer.CreateTimer API. Here is the click event handler for the button for Scenario 2 - Submit work item using Timer.

private void buttonScenario2SubmitWorkitemUsingTimer_Click
   (object sender, RoutedEventArgs e)
   TimeSpan delay = TimeSpan.FromMilliseconds
   ThreadPoolTimer DelayTimer = ThreadPoolTimer.CreateTimer(
      async (timer) =>
         await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
         () =>
            textBoxStatus.Text = "Scenario 2 completed";

Thread pools also can be used for periodic timers where you want to be apprised at every interval. This can be done by using the ThreadPoolTimer.CreatePeriodicTimer API. We will use it for the event handler for the button for Scenario 3.

private void buttonScenario3SubmitWorkitemUsingPeriodicTimer_Click
   (object sender, RoutedEventArgs e)
   int count = 0;
   TimeSpan delay = TimeSpan.FromSeconds(double.Parse
   ThreadPoolTimer PeriodicTimer =
      async (timer) =>
         await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
         () =>
            textBoxStatus.Text = "Scenario 3 called. Count "
               + count.ToString() ;

Our application is now complete. We now can run the application. When the specific task is complete, or the specific time has elapsed in the execution of the task, the status text is updated.

You can download a sample of this code at the bottom of this article.


In this article, we learned about thread pool basics and how to build a simple Windows application that uses thread pools to perform asynchronous tasks.


About the Author

Vipul Patel is a technology geek based in Seattle. He can be reached at You can visit his LinkedIn profile at

Related Articles



  • engineer

    Posted by vinrao on 01/17/2016 10:33pm

    how is synchronization achieved between multiple background threads dispatched using a ThreadPool class? I don't seem to find any synchronization primitives under windows.System.threading.

    • Threadpooltimers

      Posted by Rab on 08/21/2016 04:54am

      Hi Vipul, just wanted to say great tutorial it's the first tutorial where I actual got the thing working, one question though would you know how to cancel a periodic timer once it has started running I have tried various methods and nothing seems to work. if you use your periodic example above and just show how to cancel this that would be great. if however you have never tried or don't have time your tutorial was still brilliant mate. Regards Rab

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date