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 ทำงานเสร้จสมบูรณ์
|