Submit Work With Priority to Thread Pool in Windows Store Application

This article will demonstrate you to creating work item to thread pool with the specified priority such as low, normal and high in Windows Store application.

This article will describe you about the threading pool concept in Windows Store Apps. Thread is basic unit of Process. In the Windows Store Application we can easily implement thread pooling using Threading APIs.

In this article I will explain how you can assign a work in a separate thread by submitting a work item to the thread pool with the specified priority. Thread programming allows the programmer to maintain the UI more responsive while a work takes noticeable amount of time to completing, and makes able to complete multiple tasks in parallel.

Now, let's start to create an application to submit work item to thread pool with their priority.

Step 1

Select a Blank Windows Store Application using C#.

Step 2

Here I create some UI markup.

<Grid x:Name="LayoutRoot" Background="White">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

        <Grid x:Name="Input" Grid.Row="0">

            <Grid.RowDefinitions>

                <RowDefinition Height="Auto"/>

                <RowDefinition Height="Auto"/>

                <RowDefinition Height="*"/>

            </Grid.RowDefinitions>     

            <StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Row="1">

                <TextBlock Style="{StaticResource BasicTextStyle}" Margin="0,10,10,0" Text="Priority"></TextBlock>

                <ComboBox x:Name="Priority" SelectedIndex="0">

                    <ComboBoxItem>Low</ComboBoxItem>

                    <ComboBoxItem>Normal</ComboBoxItem>

                    <ComboBoxItem>High</ComboBoxItem>

                </ComboBox>

                <Button x:Name="CreateThreadPoolWorkItemButton" Content="Create" Margin="0,0,10,0" Click="CreateThreadPoolWorkItem" IsEnabled="True" Grid.Row="2"/>

                <Button x:Name="CancelThreadPoolWorkItemButton" Content="Cancel" Margin="0,0,10,0" Click="CancelThreadPoolWorkItem" IsEnabled="False" Grid.Row="2"/>

            </StackPanel>

        </Grid>

        <Grid x:Name="Output" Grid.Row="1">

            <StackPanel>

                <TextBlock Style="{StaticResource HeaderTextStyle}" TextWrapping="Wrap" Text="Thread pool work item" />

                <TextBlock x:Name="WorkItemInfo" Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap" Text="" />

                <TextBlock x:Name="WorkItemStatus" Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap" Text="Not created" />

            </StackPanel>

        </Grid>
</Grid>

Step 3

For creating a thread pool, here I create a custom class.

class ThreadPoolCustomClass

{

   public static ThreadPoolTimer DelayTimer;

   public static DelayTimer DelayTimerScenario;

   public static int DelayTimerMilliseconds = 0;

   public static string DelayTimerInfo = "";

   public static Status DelayTimerStatus = Status.Unregistered;

   public static int DelayTimerSelectedIndex = 0;

   public static ThreadPoolTimer PeriodicTimer;

   public static PeriodicTimer PeriodicTimerScenario;

   public static long PeriodicTimerCount = 0;

   public static int PeriodicTimerMilliseconds = 0;

   public static string PeriodicTimerInfo = "";

   public static Status PeriodicTimerStatus = Status.Unregistered;

   public static int PeriodicTimerSelectedIndex = 0;

   public static IAsyncAction ThreadPoolWorkItem;

   public static WorkItem WorkItemScenaioro;

   public static WorkItemPriority WorkItemPriority = WorkItemPriority.Normal;

   Public static Status WorkItemStatus;

   public static int WorkItemSelectedIndex = 1;

}

Step 4

Now, Create a thread pool work item with specified priority.

switch (Priority.SelectionBoxItem.ToString())

{

    case "Low":

      ThreadPoolCustomClass.WorkItemPriority = WorkItemPriority.Low;

         break;

    case "Normal":

      ThreadPoolCustomClass.WorkItemPriority = WorkItemPriority.Normal;

         break;

    case "High":

      ThreadPoolCustomClass.WorkItemPriority = WorkItemPriority.High;

        break;

}

Step 5

Submit a work item to specified thread pool. Here I calling RunAsync method of ThreadPool Class. Supply a lambda to do the work.

ThreadPoolCustomClass.ThreadPoolWorkItem = Windows.System.Threading.ThreadPool.RunAsync((source) =>

{                

    long count = 0;

    long oldProgress = 0;

    while (count < maxCount)

    {                     

       if (source.Status == AsyncStatus.Canceled)

       {

          break;

       }                     

       System.Threading.Interlocked.Increment(ref count);

           // Update work item progress in the UI.

       long currentProgress = (long)(((double)count / (double)maxCount) * 100);

       if (currentProgress > oldProgress)

       {

          var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.High,() =>

                        {

                           ThreadPoolCustomClass.WorkItemScenaioro.UpdateWorkItemProgressUI(currentProgress);

                          });

                        }

 

           oldProgress = currentProgress;

         }

   },

ThreadPoolCustomClass.WorkItemPriority);

Note: In the above code Use CoreDispatcher.RunAsync to access the UI thread and show progress from the work item.

Step 6

Register a completed-event handler to Handle work item completion.
 

ThreadPoolCustomClass.ThreadPoolWorkItem.Completed = new AsyncActionCompletedHandler(async (IAsyncAction source, AsyncStatus status) =>

{

   await Dispatcher.RunAsync(CoreDispatcherPriority.High,() =>

   {

      switch (status)

      {

         case AsyncStatus.Started:

           ThreadPoolCustomClass.WorkItemScenaioro.UpdateUI(Status.Started);

             break;

         case AsyncStatus.Completed:

           ThreadPoolCustomClass.WorkItemScenaioro.UpdateUI(Status.Completed);

              break;

         case AsyncStatus.Canceled:

            ThreadPoolCustomClass.WorkItemScenaioro.UpdateUI(Status.Canceled);

               break;

        }

     });

});

 

UpdateUI(Status.Started);

Step 7

At last updates the UI with the result of the work item submitted in Step 1 and shows the updated status of performing the work using the thread with a priority.

public void UpdateUI(Status status)

{

   ThreadPoolCustomClass.WorkItemStatus = status;

   WorkItemStatus.Text = status.ToString("g");

   WorkItemInfo.Text = string.Format("Work item priority = {0}", ThreadPoolCustomClass.WorkItemPriority.ToString("g"));

   var createButtonEnabled = (status != Status.Started);

   CreateThreadPoolWorkItemButton.IsEnabled = createButtonEnabled;

   CancelThreadPoolWorkItemButton.IsEnabled = !createButtonEnabled;

}

public
 void UpdateWorkItemProgressUI(long percentComplete)
{
   WorkItemStatus.Text = string.Format("Progress: {0}%", percentComplete.ToString());
}

To Cancel the Work Item from the Thread Pool.

private void CancelThreadPoolWorkItem(object sender, RoutedEventArgs args)

{

    if (ThreadPoolCustomClass.ThreadPoolWorkItem != null)

    {

                ThreadPoolCustomClass.ThreadPoolWorkItem.Cancel();

    }

}

threa-pool-with-priority-in-windows-store-apps.jpg
thread-pool-in-windows-store-apps.jpg