Windows Phone and BackgroundWorker       | 
   
 
			  
			  
                Windows Phone and BackgroundWorker ในการเขียน Application บน Windows Phone บางครังอาจจะต้องจำเป็นที่จะสั้งให้โปรแกรมทำงานอยู่เบื้องหลัง (Background Process) เช่นในขณะที่หน้าจอ App กำลังแสดลผลอยู่นั้น อาจจะต้องการเขียน Process บางตัวไปดึงหรืออ่านข้อมูลจาก Server และนำผลลัพธ์ที่ได้มาแสดงผลบนหน้า Page และวิธีที่ได้รับความนิยมก็คือการใช้ Class ของ BackgroundWorker สำหรับการทำงานของ BackgroundWorker จะเป็น Background Process ในรูปแบบของ Thread และในขณะที่โปรแกรมกำลังทำงานโปรแกรมจะไม่ค้าง และสามารถสั่งให้ทำงานได้หลาย ๆ Thread เช่นเดียวกัน ใน BackgroundWorker จะมี Event Method อยู่ 3 ตัวคือ  DoWork (สั่งให้ทำงาน) , ProgressChanged (แสดงสถานะการทำงาน ซึ่งจะได้ผลลัพธ์มาจาก DoWork) และ RunWorkerCompleted (เมื่อทำงานเสร็จสิ้น) ดูตัวอย่างเพื่อความเข้าใจ 
 
BackgroundWorker Syntax 
   Private WithEvents backgroundWorker As BackgroundWorker
    Private Sub btnStart_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
        backgroundWorker = New BackgroundWorker
        backgroundWorker.WorkerReportsProgress = True
        backgroundWorker.WorkerSupportsCancellation = True
        AddHandler backgroundWorker.DoWork, AddressOf backgroundWorker_DoWork
        AddHandler backgroundWorker.ProgressChanged, AddressOf backgroundWorker_ProgressChanged
        AddHandler backgroundWorker.RunWorkerCompleted, AddressOf backgroundWorker_RunWorkerCompleted
        backgroundWorker.RunWorkerAsync()
    End Sub
    Private Sub backgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs)
    End Sub
    Private Sub backgroundWorker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
    End Sub
    Private Sub backgroundWorker_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
    End Sub
 
ตัวอย่างการใช้รูปแบบการใช้ BackgroundWorker  และ Event ของ DoWork, ProgressChanged และ RunWorkerCompleted 
 
และในการเขียน App ควบคุมการทำงานในหน้า Page การสั่งให้ BackgroundWorker ทำงาน สามารถใช้งานร่วมกับ Timer ที่จะตั้งเวลาให้โปรแกรมทำงานตามระยะและเวลาที่กำหนดได้ 
 
Example การใช้งาน BackgroundWorker   แบบง่าย ๆ  
 
MainPage.xaml 
 
  
 
    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>
        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button Content="Start" Height="72" HorizontalAlignment="Left" Margin="40,156,0,0" Name="btnStart" Click="btnStart_Click" VerticalAlignment="Top" Width="160" />
            <Button Content="Cancel" Height="72" HorizontalAlignment="Left" Margin="240,156,0,0" Name="btnCancel" Click="btnCancel_Click" VerticalAlignment="Top" Width="160" />
            <TextBlock Height="30" HorizontalAlignment="Left" Margin="12,99,0,0" Name="txtResult" Text="Result" VerticalAlignment="Top" Width="438" TextAlignment="Center" />
        </Grid>
        <ProgressBar Height="4" HorizontalAlignment="Left" Margin="8,64,0,0" Name="ProgressBar1" VerticalAlignment="Top" Width="460" Grid.Row="1" />
    </Grid>
 
 
 
 
MainPage.xaml.vb (VB.NET) 
Imports System.ComponentModel
Partial Public Class MainPage
    Inherits PhoneApplicationPage
    ' Constructor
    Public Sub New()
        InitializeComponent()
    End Sub
    Private WithEvents backgroundWorker As BackgroundWorker
    Private Sub btnStart_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Me.ProgressBar1.Maximum = 100
        Me.ProgressBar1.Value = 0
        backgroundWorker = New BackgroundWorker
        backgroundWorker.WorkerReportsProgress = True
        backgroundWorker.WorkerSupportsCancellation = True
        AddHandler backgroundWorker.DoWork, AddressOf backgroundWorker_DoWork
        AddHandler backgroundWorker.ProgressChanged, AddressOf backgroundWorker_ProgressChanged
        AddHandler backgroundWorker.RunWorkerCompleted, AddressOf backgroundWorker_RunWorkerCompleted
        backgroundWorker.RunWorkerAsync()
    End Sub
    Private Sub btnCancel_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
        backgroundWorker.CancelAsync()
    End Sub
    Private Sub backgroundWorker_DoWork(ByVal sender As System.Object, _
       ByVal e As DoWorkEventArgs)
        Dim i As Integer
        For i = 1 To 100
            If (backgroundWorker.CancellationPending = True) Then
                e.Cancel = True
                Exit For
            Else
                System.Threading.Thread.Sleep(100)
                backgroundWorker.ReportProgress(i)
            End If
        Next
    End Sub
    Private Sub backgroundWorker_ProgressChanged(sender As Object,
         e As ProgressChangedEventArgs)
        Me.txtResult.Text = "Process Working..."
        Me.ProgressBar1.Value = e.ProgressPercentage
    End Sub
    Private Sub backgroundWorker_RunWorkerCompleted(sender As Object,
     e As RunWorkerCompletedEventArgs)
        If e.Cancelled = True Then
            Me.txtResult.Text = "Process Cancel!"
        ElseIf e.Error IsNot Nothing Then
            Me.txtResult.Text = "Error: " & e.Error.Message
        Else
            Me.txtResult.Text = "Process Completed."
        End If
    End Sub
End Class
 
MainPage.xaml.cs (C#) 
using System;
using System.Windows;
using System.Net;
using System.IO;
using System.Text;
using System.IO.IsolatedStorage;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.ComponentModel;
namespace PhoneApp
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
        private BackgroundWorker backgroundWorker;
        private void btnStart_Click(System.Object sender, System.Windows.RoutedEventArgs e)
        {
            this.ProgressBar1.Maximum = 100;
            this.ProgressBar1.Value = 0;
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
            backgroundWorker.DoWork += backgroundWorker_DoWork;
            backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
            backgroundWorker.RunWorkerAsync();
        }
        private void btnCancel_Click(System.Object sender, System.Windows.RoutedEventArgs e)
        {
            backgroundWorker.CancelAsync();
        }
        private void backgroundWorker_DoWork(System.Object sender, DoWorkEventArgs e)
        {
            int i = 0;
            for (i = 1; i <= 100; i++)
            {
                if ((backgroundWorker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break; // TODO: might not be correct. Was : Exit For
                }
                else
                {
                    System.Threading.Thread.Sleep(100);
                    backgroundWorker.ReportProgress(i);
                }
            }
        }
        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.txtResult.Text = "Process Working...";
            this.ProgressBar1.Value = e.ProgressPercentage;
        }
        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                this.txtResult.Text = "Process Cancel!";
            }
            else if (e.Error != null)
            {
                this.txtResult.Text = "Error: " + e.Error.Message;
            }
            else
            {
                this.txtResult.Text = "Process Completed.";
            }
        }
    }
}
 
ในตัวอย่างนี้มี Code ทั้งที่เป็น VB.NET และ C# และสามารถดาวน์โหลด All Code ทั้งหมดได้จากส่วนท้ายของบทความ (Login สมาชิกก่อน) 
 
 
 
Screenshot 
 
  
 
คลิกที่ปุ่ม Start เพื่อเริ่มการทำงานของ BackgroundWorker   
 
  
 
เมื่อ BackgroundWorker    ทำงานเสร้จสมบูรณ์              
  
              			
			  
								  
			  
  
                          
  |