Saturday, February 04, 2012
Download

UsingThreadpoolInSilverlight2.zip

Purpose

Threadpool allows you to spawn multiple background thread allowing you to process for in this example to allow multiple images to be downloaded.

You can apply this simple but very poweful example to spawn worker threads to perform time consuming executions.

UsingThreadpoolInSilverlight2.zip

Purpose

Threadpool allows you to spawn multiple background thread allowing you to process for in this example to allow multiple images to be downloaded.

You can apply this simple but very poweful example to spawn worker threads to perform time consuming executions.



Step By Step

Follow the instruction from Creating Silverlight 2 Project

Page.xaml

<UserControl x:Class="UsingThreadpoolInSilverlight2.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="496" Height="374">
 
    <Grid x:Name="LayoutRoot" Background="White">
      <TextBox Height="22" Margin="8,59,156,0" 
               VerticalAlignment="Top" 
               Text="http://silverlight.newagesolution.net/images/test/01.jpg" 
               TextWrapping="Wrap" x:Name="txt1" />
      <TextBox Height="22" Margin="8,85,156,0" 
               VerticalAlignment="Top" 
               Text="http://silverlight.newagesolution.net/images/test/02.jpg" 
               TextWrapping="Wrap" x:Name="txt2" />
      <TextBox Height="22" Margin="8,111,156,0" 
               VerticalAlignment="Top" 
               Text="http://silverlight.newagesolution.net/images/test/03.jpg" 
               TextWrapping="Wrap" x:Name="txt3" />
      <TextBox Margin="8,137,156,0" 
               Text="http://silverlight.newagesolution.net/images/test/04.jpg" 
               TextWrapping="Wrap" Height="22" 
               VerticalAlignment="Top" x:Name="txt4" />
      <TextBox Margin="8,163,156,0" 
               Text="http://silverlight.newagesolution.net/images/test/05.jpg" 
               TextWrapping="Wrap" VerticalAlignment="Top" 
               Height="22" x:Name="txt5" />
      <TextBlock Height="17" HorizontalAlignment="Left" 
                 Margin="8,22,0,0" VerticalAlignment="Top" 
                 Width="85" Text="Image Urls" TextWrapping="Wrap"/>
      <Button Height="22" HorizontalAlignment="Right" 
              Margin="0,59,102,0" VerticalAlignment="Top" Width="48" 
              Content="Display" x:Name="btn1" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" Margin="0,163,102,0" 
              VerticalAlignment="Top" Width="48" Content="Display" 
              x:Name="btn5" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" 
              Margin="0,137,102,0" VerticalAlignment="Top" Width="48" 
              Content="Display" x:Name="btn4" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" Margin="0,111,102,0" 
              VerticalAlignment="Top" Width="48" Content="Display" 
              x:Name="btn3" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" Margin="0,85,102,0" 
              VerticalAlignment="Top" Width="48" Content="Display" 
              x:Name="btn2" IsEnabled="False"/>
      <TextBlock Foreground="#FF000000" Height="126" 
                 HorizontalAlignment="Right" Margin="0,59,8,0" 
                 VerticalAlignment="Top" Width="90" FontSize="18" 
                 Text="" TextWrapping="Wrap" x:Name="txtStatus"/>
      <StackPanel Height="137" VerticalAlignment="Bottom" 
                  Margin="8,0,23,27" x:Name="imagePlaceholder"/>
      <Button Height="25" Margin="97,22,0,0" VerticalAlignment="Top" 
              Content="Start Loading" Width="100" HorizontalAlignment="Left" 
              x:Name="btnStart"/>
    </Grid>
</UserControl>

Page.xaml.cs

Here we used anonymous method along with Threadpool  to initiate image loading proces:

ThreadPool.QueueUserWorkItem(delegate(object notUsed)
        {
          LoadImage(imageIndex);
        });

LoadImage method simulated worker thread randomly being done downloading the images with thread Sleep.

Notice that we are using

this.Dispatcher.BeginInvoke(newImageHandler, args);

which will allows the control to be returned immediately to the calling object after being called.

And the  Dispatcher guarantees that this code is executed on the main UI thread.

Full Code is shown below:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Browser;
using System.Threading;
using System.Windows.Media.Imaging;
 
namespace UsingThreadpoolInSilverlight2
{
  public partial class Page : UserControl
  {
    private const int MAX_IMAGES = 5;
    private delegate void NewImagesHandler(int imageIndex);
 
    // Constructor
    public Page()
    {
      InitializeComponent();
 
      // assign events to the button clicks
      btnStart.Click += new RoutedEventHandler(BtnStart_Click);
      for (int i = 1; i <= MAX_IMAGES; i++)
      {
        Button btn = (Button)this.LayoutRoot.FindName("btn" + i.ToString());
        btn.Click += new RoutedEventHandler(Btn_Click);
      }
    }
 
    // Click event handlers for buttons and images
    private void Btn_Click(object sender, RoutedEventArgs e)
    {
      ResetImage();
 
      Button btn = (Button)sender;
      string imageIndex = btn.Name.Substring(3, 1);
      Image img = (Image)imagePlaceholder.FindName("img" + imageIndex);
      img.Visibility = Visibility.Visible;
 
    }
    private void BtnStart_Click(object sender, RoutedEventArgs e)
    {
      ResetControls();
      LoadResources();
    }
    private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
      string browserWindowOptions = "";
      HtmlPage.Window.Navigate(new Uri("http://www.google.com"), "_blank", browserWindowOptions);
    }
 
    // Set visibility of all the images to collapsed
    private void ResetImage()
    {
      for (int i = 1; i <= this.imagePlaceholder.Children.Count; i++)
      {
        Image img = (Image)this.LayoutRoot.FindName("img" + i.ToString());
        img.Visibility = Visibility.Collapsed;
      }
    }
    private void ResetControls()
    {
      while (imagePlaceholder.Children.Count > 0)
      {
        imagePlaceholder.Children.RemoveAt(0);
      }
      txtStatus.Text = "";
      for (int i = 1; i <= MAX_IMAGES; i++)
      {
        Button btn = (Button)this.LayoutRoot.FindName("btn" + i.ToString());
        btn.IsEnabled = false;
      }
    }
 
    // Used for loading images in background in parallel
    private void LoadResources()
    {
      for (int i = 1; i <= MAX_IMAGES; i++)
      {
        int imageIndex = i;
        // Load rest of the images in background
        ThreadPool.QueueUserWorkItem(delegate(object notUsed)
        {
          LoadImage(imageIndex);
        });
      }
    }
    private void LoadImage(int imageIndex)
    {
      // Simulate some delay
      System.Threading.Thread.Sleep(imageIndex * 1000);
 
      // Update UI
      NewImagesHandler newImageHandler = new NewImagesHandler(AddNewImage);
      object[] args = { imageIndex };
      this.Dispatcher.BeginInvoke(newImageHandler, args);
    }
    private void AddNewImage(int imageIndex)
    {
      // Find text box. Assumes text box is named txt[1..n]
      TextBox txt = (TextBox)this.LayoutRoot.FindName("txt" + imageIndex.ToString());
      // Get image url from text box
      string url = txt.Text.Contains("http://") ? txt.Text : "http://" + txt.Text;
      Uri imageUrl = new Uri(url);
      // Show only first image visible
      Visibility isImageVisible = imageIndex.Equals(1) ? Visibility.Visible : Visibility.Collapsed;
 
      // Add images to placeholder
      Image image = new Image();
      image.Name = "img" + imageIndex;
      image.Width = 400;
      image.Height = 137;
      image.Stretch = Stretch.Uniform;
      image.Source = new BitmapImage(imageUrl);
      image.MouseLeftButtonDown += new MouseButtonEventHandler(Image_MouseLeftButtonDown);
      image.Visibility = isImageVisible;
      imagePlaceholder.Children.Add(image);
 
      // Find Button. Assumes Button is named btn[1..n]
      // Then Enable button
      Button btn = (Button)this.LayoutRoot.FindName("btn" + imageIndex.ToString());
      btn.IsEnabled = true;
 
      // Update Status to Status Label
      txtStatus.Text += "Loaded" + Environment.NewLine;
    }
  }
}

 

Follow the instruction from Creating Silverlight 2 Project

Page.xaml

<UserControl x:Class="UsingThreadpoolInSilverlight2.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="496" Height="374">
 
    <Grid x:Name="LayoutRoot" Background="White">
      <TextBox Height="22" Margin="8,59,156,0" 
               VerticalAlignment="Top" 
               Text="http://silverlight.newagesolution.net/images/test/01.jpg" 
               TextWrapping="Wrap" x:Name="txt1" />
      <TextBox Height="22" Margin="8,85,156,0" 
               VerticalAlignment="Top" 
               Text="http://silverlight.newagesolution.net/images/test/02.jpg" 
               TextWrapping="Wrap" x:Name="txt2" />
      <TextBox Height="22" Margin="8,111,156,0" 
               VerticalAlignment="Top" 
               Text="http://silverlight.newagesolution.net/images/test/03.jpg" 
               TextWrapping="Wrap" x:Name="txt3" />
      <TextBox Margin="8,137,156,0" 
               Text="http://silverlight.newagesolution.net/images/test/04.jpg" 
               TextWrapping="Wrap" Height="22" 
               VerticalAlignment="Top" x:Name="txt4" />
      <TextBox Margin="8,163,156,0" 
               Text="http://silverlight.newagesolution.net/images/test/05.jpg" 
               TextWrapping="Wrap" VerticalAlignment="Top" 
               Height="22" x:Name="txt5" />
      <TextBlock Height="17" HorizontalAlignment="Left" 
                 Margin="8,22,0,0" VerticalAlignment="Top" 
                 Width="85" Text="Image Urls" TextWrapping="Wrap"/>
      <Button Height="22" HorizontalAlignment="Right" 
              Margin="0,59,102,0" VerticalAlignment="Top" Width="48" 
              Content="Display" x:Name="btn1" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" Margin="0,163,102,0" 
              VerticalAlignment="Top" Width="48" Content="Display" 
              x:Name="btn5" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" 
              Margin="0,137,102,0" VerticalAlignment="Top" Width="48" 
              Content="Display" x:Name="btn4" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" Margin="0,111,102,0" 
              VerticalAlignment="Top" Width="48" Content="Display" 
              x:Name="btn3" IsEnabled="False"/>
      <Button Height="22" HorizontalAlignment="Right" Margin="0,85,102,0" 
              VerticalAlignment="Top" Width="48" Content="Display" 
              x:Name="btn2" IsEnabled="False"/>
      <TextBlock Foreground="#FF000000" Height="126" 
                 HorizontalAlignment="Right" Margin="0,59,8,0" 
                 VerticalAlignment="Top" Width="90" FontSize="18" 
                 Text="" TextWrapping="Wrap" x:Name="txtStatus"/>
      <StackPanel Height="137" VerticalAlignment="Bottom" 
                  Margin="8,0,23,27" x:Name="imagePlaceholder"/>
      <Button Height="25" Margin="97,22,0,0" VerticalAlignment="Top" 
              Content="Start Loading" Width="100" HorizontalAlignment="Left" 
              x:Name="btnStart"/>
    </Grid>
</UserControl>

Page.xaml.cs

Here we used anonymous method along with Threadpool  to initiate image loading proces:

ThreadPool.QueueUserWorkItem(delegate(object notUsed)
        {
          LoadImage(imageIndex);
        });

LoadImage method simulated worker thread randomly being done downloading the images with thread Sleep.

Notice that we are using

this.Dispatcher.BeginInvoke(newImageHandler, args);

which will allows the control to be returned immediately to the calling object after being called.

And the  Dispatcher guarantees that this code is executed on the main UI thread.

Full Code is shown below:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Browser;
using System.Threading;
using System.Windows.Media.Imaging;
 
namespace UsingThreadpoolInSilverlight2
{
  public partial class Page : UserControl
  {
    private const int MAX_IMAGES = 5;
    private delegate void NewImagesHandler(int imageIndex);
 
    // Constructor
    public Page()
    {
      InitializeComponent();
 
      // assign events to the button clicks
      btnStart.Click += new RoutedEventHandler(BtnStart_Click);
      for (int i = 1; i <= MAX_IMAGES; i++)
      {
        Button btn = (Button)this.LayoutRoot.FindName("btn" + i.ToString());
        btn.Click += new RoutedEventHandler(Btn_Click);
      }
    }
 
    // Click event handlers for buttons and images
    private void Btn_Click(object sender, RoutedEventArgs e)
    {
      ResetImage();
 
      Button btn = (Button)sender;
      string imageIndex = btn.Name.Substring(3, 1);
      Image img = (Image)imagePlaceholder.FindName("img" + imageIndex);
      img.Visibility = Visibility.Visible;
 
    }
    private void BtnStart_Click(object sender, RoutedEventArgs e)
    {
      ResetControls();
      LoadResources();
    }
    private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
      string browserWindowOptions = "";
      HtmlPage.Window.Navigate(new Uri("http://www.google.com"), "_blank", browserWindowOptions);
    }
 
    // Set visibility of all the images to collapsed
    private void ResetImage()
    {
      for (int i = 1; i <= this.imagePlaceholder.Children.Count; i++)
      {
        Image img = (Image)this.LayoutRoot.FindName("img" + i.ToString());
        img.Visibility = Visibility.Collapsed;
      }
    }
    private void ResetControls()
    {
      while (imagePlaceholder.Children.Count > 0)
      {
        imagePlaceholder.Children.RemoveAt(0);
      }
      txtStatus.Text = "";
      for (int i = 1; i <= MAX_IMAGES; i++)
      {
        Button btn = (Button)this.LayoutRoot.FindName("btn" + i.ToString());
        btn.IsEnabled = false;
      }
    }
 
    // Used for loading images in background in parallel
    private void LoadResources()
    {
      for (int i = 1; i <= MAX_IMAGES; i++)
      {
        int imageIndex = i;
        // Load rest of the images in background
        ThreadPool.QueueUserWorkItem(delegate(object notUsed)
        {
          LoadImage(imageIndex);
        });
      }
    }
    private void LoadImage(int imageIndex)
    {
      // Simulate some delay
      System.Threading.Thread.Sleep(imageIndex * 1000);
 
      // Update UI
      NewImagesHandler newImageHandler = new NewImagesHandler(AddNewImage);
      object[] args = { imageIndex };
      this.Dispatcher.BeginInvoke(newImageHandler, args);
    }
    private void AddNewImage(int imageIndex)
    {
      // Find text box. Assumes text box is named txt[1..n]
      TextBox txt = (TextBox)this.LayoutRoot.FindName("txt" + imageIndex.ToString());
      // Get image url from text box
      string url = txt.Text.Contains("http://") ? txt.Text : "http://" + txt.Text;
      Uri imageUrl = new Uri(url);
      // Show only first image visible
      Visibility isImageVisible = imageIndex.Equals(1) ? Visibility.Visible : Visibility.Collapsed;
 
      // Add images to placeholder
      Image image = new Image();
      image.Name = "img" + imageIndex;
      image.Width = 400;
      image.Height = 137;
      image.Stretch = Stretch.Uniform;
      image.Source = new BitmapImage(imageUrl);
      image.MouseLeftButtonDown += new MouseButtonEventHandler(Image_MouseLeftButtonDown);
      image.Visibility = isImageVisible;
      imagePlaceholder.Children.Add(image);
 
      // Find Button. Assumes Button is named btn[1..n]
      // Then Enable button
      Button btn = (Button)this.LayoutRoot.FindName("btn" + imageIndex.ToString());
      btn.IsEnabled = true;
 
      // Update Status to Status Label
      txtStatus.Text += "Loaded" + Environment.NewLine;
    }
  }
}

 



Demo
Minimize


 

 

Privacy Statement  |  Terms Of Use
Copyright 2009 by New Age Solution Inc.