Windows Phone and Thread (Silverlight) |
Windows Phone and Thread (Silverlight) สำหรับ Thread สามารถกำหนดเป็น Background Process ใช้สำหรับการจัดการกับ Process ที่เกิดขึ้นพร้อม ๆ กันหลาย Process โดย Process เหล่าต่าง ๆ ที่ถูกควบคุมด้วย Thread จะแยกการทำงานของแต่ล่ะ Prcess อิสระต่อกัน ทั้งค่าตัวแปรต่าง ๆ ที่เกิดขึ้นและถูกเก็บลงในหน่วยความจำ ที่เกิดขึ้นในขณะนั้น ๆ ซึ่งในกรณีที่เราไม่ได้ใช้ Thread เข้ามาจัดการกับ Process ต่าง ๆ บน Application ปัญหาที่เกิดขึ้นคือ เมื่อเกิด Process เหล่านั้นขึ้นโปรแกรมอาจจะหน้าจอค้าง และรอจนกว่าการทำงานนั้น ๆ จะเสร็จสิ้น หรือกรณีที่มี Process ซ้ำซ้อน Process ใหม่อาจจะไปหยุดการทำงานของ Process ที่กำลังทำงานอยู่และการใช้ค่าตัวแปรต่าง ๆ อาจจะซ้ำซ้อนกัน
Thread ที่ใช้ควบคุม Process ในกรณีที่เกิด Process ต่าง ๆ ขึ้น Process ที่ถูกให้สั่งทำงานไปแล้ว จะสามารถทำงานอื่น ๆ ต่อไปได้จนเสร็จสิ้นงานของตัวเอง และในกรณีที่กำหนดเป็น Backgroud Process ในหน้าจอ Application หนึ่ง ๆ นั้น ในระหว่างที่ Process กำลังทำงานใน Thread สามารถสั่งให้ Process นั้น ๆ แสดงผลลัพธ์ออกทางหน้าจอ Interface หรือแสดงผลบน Controls ตัวเดียวกันได้เช่นเดียวกัน
การสร้าง Thread
VB.NET
Private Sub btnStartThread_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf ThreadStart)
thread.Start()
End Sub
Private Sub ThreadStart()
'*** Process in Thread
'*** Process in Thread
'*** Process in Thread
'*** Process in Thread
End Sub
C#
private void btnStartThread_Click(object sender, System.Windows.RoutedEventArgs e)
{
System.Threading.Thread thread = new System.Threading.Thread(ThreadStart);
thread.Start();
}
private void ThreadStart()
{
// *** Process in Thread
// *** Process in Thread
// *** Process in Thread
// *** Process in Thread
}
จาก Code ที่เป็น VB.NET และ C# หลังจากที่ผู้ใช้คลิกที่ปุ่ม Button btnStartThread ก็จะมีการสั่งให้ ThreadStart() ทำงาน โดยผู้ใช้สามารถคลิกปุ่มหลาย ๆ ครั้งเพื่อให้ Thread ทำงาหลาย ๆ Thread และในขณะที่กำลังทำงาน ThreadStart() ที่มีคำสั่งต่าง ๆ ข้างในก็ทำงานของตัวเองจนเสร็จสิ้น โดยไม่เกี่ยวข้องกับ Prcess ที่กำลังเกิดขึ้นใหม่
การแสดงค่าในขณะที่ Thread กำลังทำงาน
- แบบที่ 1 สร้าง Action Method
VB.NET
Private Sub btnStartThread_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf ThreadStart)
thread.Start()
End Sub
Private Sub ThreadStart()
Dim strReturn As String
Dim display As New Action(Of String)(AddressOf AddTextByDispatcher)
'*** Process in Thread
'*** Process in Thread
strReturn = "String Return"
Dispatcher.BeginInvoke(display, strReturn) ' call AddTextByDispatcher()
'*** Process in Thread
'*** Process in Thread
End Sub
Private Sub AddTextByDispatcher(ByVal strReturn As String)
Me.txtResult.Text = strReturn
End Sub
C#
private void btnStartThread_Click(object sender, System.Windows.RoutedEventArgs e)
{
System.Threading.Thread thread = new System.Threading.Thread(ThreadStart);
thread.Start();
}
private void ThreadStart()
{
string strReturn;
Action<string> display = AddTextByDispatcher;
// *** Process in Thread
// *** Process in Thread
strReturn = "String Return";
Dispatcher.BeginInvoke(display, strReturn);
// call AddTextByDispatcher()
// *** Process in Thread
// *** Process in Thread
}
private void AddTextByDispatcher(string strReturn)
{
this.txtResult.Text = strReturn;
}
- แบบที่ 2 ใช้การ Delegate Method
VB.NET
Private Sub btnStartThread_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf ThreadStart)
thread.Start()
End Sub
Private Sub ThreadStart()
Dim strReturn As String
'*** Process in Thread
'*** Process in Thread
strReturn = "String Return"
Dispatcher.BeginInvoke(New AddTextDelegate(AddressOf AddTextByDispatcher), strReturn)
'*** Process in Thread
'*** Process in Thread
End Sub
Private Delegate Sub AddTextDelegate(ByVal text As String)
Private Sub AddTextByDispatcher(ByVal strReturn As String)
Me.txtResult.Text = strReturn
End Sub
C#
public delegate void AddTextDelegate(string text);
private void btnStartThread_Click(object sender, System.Windows.RoutedEventArgs e)
{
System.Threading.Thread thread = new System.Threading.Thread(ThreadStart);
thread.Start();
}
private void ThreadStart()
{
string strReturn;
// *** Process in Thread
// *** Process in Thread
strReturn = "String Return";
Dispatcher.BeginInvoke(new AddTextDelegate(AddTextByDispatcher), strReturn);
// *** Process in Thread
// *** Process in Thread
}
private void AddTextByDispatcher(string strReturn)
{
this.txtResult.Text = strReturn;
}
จากทั้ง 2 แบบจะเห็นว่าในระหว่างที่ Thread กำลังทำงาน สามารถที่จะส่งค่าหรือ return ค่าไปยังหน้าจอของ Application ผ่านทั้ง 2 วิธีคือ Action Method และ Delegate Method ด้วยการใช้ Dispatcher.BeginInvoke()
Example ตัวอย่างการทดสอบการใช้ Thread และการแสดงผลค่าในระหว่างที่ Thread กำลังทำงาน
ออกแบบหน้าจอและ Layout ดังรูป
<!--LayoutRoot contains the root grid where all other 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" Margin="12,17,0,0" Height="171">
<Grid Height="70">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<RadioButton Content="Red" Height="70" Name="rdoRed" Margin="0,0,28,0" Foreground="RED" />
<RadioButton Grid.Column="1" Content="Blue" Height="70" Name="rdoBlue" Margin="12,0,26,0" Foreground="BLUE" />
<RadioButton Grid.Column="2" Content="Green" Height="70" Name="rdoGreen" Margin="12,0" Foreground="GREEN" />
</Grid>
<Button Content="Start Thread" Height="72" Name="btnStartThread" Width="200" Click="btnStartThread_Click" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
</StackPanel>
</Grid>
VB.NET
Imports System.Windows.Threading
Partial Public Class MainPage
Inherits PhoneApplicationPage
' Constructor
Public Sub New()
InitializeComponent()
End Sub
Private SelColor As SolidColorBrush
Private Sub btnStartThread_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
If rdoRed.IsChecked = True Then
SelColor = New SolidColorBrush(Colors.Red)
ElseIf rdoBlue.IsChecked = True Then
SelColor = New SolidColorBrush(Colors.Blue)
ElseIf rdoGreen.IsChecked = True Then
SelColor = New SolidColorBrush(Colors.Green)
End If
Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf ThreadStart)
thread.Start()
End Sub
Private Sub ThreadStart()
Dim strColor As SolidColorBrush = SelColor
Dim threadID As String = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()
Dim strReturn As String
Dim display As New Action(Of String, SolidColorBrush)(AddressOf AddTextByDispatcher)
For i As Integer = 0 To 5
System.Threading.Thread.Sleep(1000)
strReturn = threadID & "- Loop(" & i & ") - " & Date.Now
Dispatcher.BeginInvoke(display, strReturn, strColor)
Next
End Sub
Private Sub AddTextByDispatcher(ByVal strReturn As String, ByVal foreColor As SolidColorBrush)
'*** Create TextBlock To ContentPanel ***'
Dim textBlock As New TextBlock
textBlock.Text = strReturn
textBlock.Foreground = foreColor
ContentPanel.Children.Add(textBlock)
End Sub
End Class
C#
private SolidColorBrush SelColor;
private void btnStartThread_Click(object sender, System.Windows.RoutedEventArgs e)
{
if ((rdoRed.IsChecked == true))
{
SelColor = new SolidColorBrush(Colors.Red);
}
else if ((rdoBlue.IsChecked == true))
{
SelColor = new SolidColorBrush(Colors.Blue);
}
else if ((rdoGreen.IsChecked == true))
{
SelColor = new SolidColorBrush(Colors.Green);
}
System.Threading.Thread thread = new System.Threading.Thread(ThreadStart);
thread.Start();
}
private void ThreadStart()
{
SolidColorBrush strColor = SelColor;
string threadID = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
string strReturn;
Action<String, SolidColorBrush> display = AddTextByDispatcher;
for (int i = 0; (i <= 5); i++)
{
System.Threading.Thread.Sleep(1000);
strReturn = threadID + "- Loop(" + i + ") - " + DateTime.Now.ToString();
Dispatcher.BeginInvoke(display, strReturn, strColor);
}
}
private void AddTextByDispatcher(string strReturn, SolidColorBrush foreColor)
{
// *** Create TextBlock To ContentPanel ***'
TextBlock textBlock = new TextBlock();
textBlock.Text = strReturn;
textBlock.Foreground = foreColor;
ContentPanel.Children.Add(textBlock);
}
จาก Code ที่เป็น VB.NET และ C# วัตถุประสงค์คือต้องการให้ผู้ใช้คลิกที่ RadioButton ซึ่งมีอยู่ 3 รายการคือ Read, Blue และ Green และคลิกที่ Button เพื่อเริ่มการทำงานของ Thread โดยจะมีการจัดเก็บค่าสีที่ได้เลือกไว้เพื่อนำไปใช้ใน Process ของ Thread
For i As Integer = 0 To 5
System.Threading.Thread.Sleep(1000)
strReturn = threadID & "- Loop(" & i & ") - " & Date.Now
Dispatcher.BeginInvoke(display, strReturn, strColor)
Next
สังเกตุว่าใน Thread จะมีการสั่งให้ Process ทำงานครั้งล่ะ 6 คือ Loop (0-5) และทุก ๆ Loop หยุด 1 วินาที และหลังจากนั้นให้ส่งผลลัพธ์ไปยังหน้าจอของ Application
Private Sub AddTextByDispatcher(ByVal strReturn As String, ByVal foreColor As SolidColorBrush)
'*** Create TextBlock To ContentPanel ***'
Dim textBlock As New TextBlock
textBlock.Text = strReturn
textBlock.Foreground = foreColor
ContentPanel.Children.Add(textBlock)
End Sub
แสดงผลลัพธ์ด้วยการแสดงผลบน TextBlock ซึ่งใน ContentPanel จะใช้ StackPanel ในการแสดงผล และจะได้ผล TextBlock ยาวลงมาเรื่อย ๆ ตามจำนวน Thread ที่เกิดขึ้น และ TextBlock แต่ล่ะรายการก็จะแสดงสีที่ได้เลือกไว้
Screenshot ทดสอบบน Emulator
หน้าจอแรกเมื่อโปรแกรมทำงาน
เราจะมาทดสอบการทำงานของ Thread ด้วยการ ทดสอบการคลิกที่ RadioButton แต่ล่ะตัว
Red -> Start Thread
Blue -> Start Thread
Green -> Thread
โดยคลิกในเวลาที่ใกล้เคียงกัน
สิ่งที่ได้เมื่อคลิก 3 รายการคือ Thread จะทำงานอยู่ 3 Process แต่ล่ะ Process ก็จะ Loop 0-5 และแสดงผลลัพธ์ออกมาทางหน้าจอ Application ซึ่งในแต่ล่ะผลลัพธ์จะแสดงค่า DateTime , Loop , ThreadID และสี Color ที่ได้เลือกไว้ในขั้นตอนแรก โดยการทำงานทั้ง 3 Process จะไม่มีการค้างหน้าจอของ Application และแต่ล่ะ Thread มีการแยกค่าตัวแปรกันอย่างชัดเจน
สรุป
จากตัวอย่างง่าย ๆ นี้เราจะได้เข้าใจหลักการพื้นฐานและการทำงานของ Thread ที่จะเข้ามาควบคุมการทำงานของ Process และจะเป็นพื้นฐานในการต่อยอดในการเขียนโปรแกรมที่มีความซับซ้อนยิ่งขึ้น และการใช้งาน Thread ก็ค่อนข่างที่จะจำเป็น ต่อการนำไปใช้ในการเขียนโปรแกรมอย่างยิ่ง ยิ่งเราได้เข้าใจ Concept และการทำงานแล้ว จะสามารถเกิด Idea ต่าง ๆ ขึ้นมากมาย หรือไม่ลองสังเกตุจาก Application ต่าง ๆ ที่ใช้อยู่บน iPhone, iPad หรือ Android หรือ Windows Phone นั้นว่า กระบวนการต่าง ๆ ที่เกิดขึ้นระหว่างการแลกเปลี่ยนข้อมูลนั้น มีแนวคิดและวิธีการอย่างไร สิ่งเหล่านี้จะช่วยให้เราเกิดไอเดีย การนำไปใช้ หรือศึกษาวิธีการต่าง ๆ ในการเขียนโปรแกรม
|
ช่วยกันสนับสนุนรักษาเว็บไซต์ความรู้แห่งนี้ไว้ด้วยการสนับสนุน Source Code 2.0 ของทีมงานไทยครีเอท
|
|
|
By : |
ThaiCreate.Com Team (บทความเป็นลิขสิทธิ์ของเว็บไทยครีเอทห้ามนำเผยแพร่ ณ เว็บไซต์อื่น ๆ) |
|
Score Rating : |
|
|
|
Create/Update Date : |
2012-09-05 21:47:09 /
2017-03-25 21:57:23 |
|
Download : |
|
|
Sponsored Links / Related |
|
|
|
|
|
|
|