在Silverlight中,使用Thread,Timer,BackgrouWorker,ThreadPool可以實現多線程開發。但是隨之而來的問題是如何跨線程訪問資源呢?下面先以Timer計時器為例講解:
示例
1、Timer.xaml
1
<
UserControl
x:Class
="ThreadDemo.Timer"
2 xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable ="d"
7 d:DesignHeight ="300" d:DesignWidth ="400" >
8
9 < Grid x:Name ="LayoutRoot" Background ="White" >
10 < ScrollViewer >
11 < StackPanel x:Name ="timerNum" >
12
13 </ StackPanel >
14 </ ScrollViewer >
15 </ Grid >
16 </ UserControl >
2 xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable ="d"
7 d:DesignHeight ="300" d:DesignWidth ="400" >
8
9 < Grid x:Name ="LayoutRoot" Background ="White" >
10 < ScrollViewer >
11 < StackPanel x:Name ="timerNum" >
12
13 </ StackPanel >
14 </ ScrollViewer >
15 </ Grid >
16 </ UserControl >
Timer.cs
1
using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.Threading;
13
14 namespace ThreadDemo
15 {
16 public partial class Timer: UserControl
17 {
18 public Timer()
19 {
20 InitializeComponent();
21 /// 實例化一個Timer時間器
22 System.Threading.TimerTimer timer = new System.Threading.TimerTimer( new TimerCallback(TimerProc));
23 /// 設定500毫秒后啟動,每隔1000毫秒執行一次
24 timer.Change( 500, 1000);
25 }
26 int flagnum;
27 public void TimerProc( object state)
28 {
29 flagnum++;
30 TextBlock _temptext = new TextBlock();
31 _temptext.Text = flagnum.ToString();
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.Threading;
13
14 namespace ThreadDemo
15 {
16 public partial class Timer: UserControl
17 {
18 public Timer()
19 {
20 InitializeComponent();
21 /// 實例化一個Timer時間器
22 System.Threading.TimerTimer timer = new System.Threading.TimerTimer( new TimerCallback(TimerProc));
23 /// 設定500毫秒后啟動,每隔1000毫秒執行一次
24 timer.Change( 500, 1000);
25 }
26 int flagnum;
27 public void TimerProc( object state)
28 {
29 flagnum++;
30 TextBlock _temptext = new TextBlock();
31 _temptext.Text = flagnum.ToString();
32 timerNum.Children.Add(_temptext);
33
34 }
35 }
36 }
F5運行程序,Visual Studio報錯,跨線程訪問無效。
這里使用TimerCallback委托指定希望Timer執行的方法,但是此方法不能在計時器線程上執行,所以這里就存在一個跨線程訪問的問題。下面調整下代碼,計時器線程將該工作委托給與該UI線程關聯的Dispatcher。使用Dispatcher.BeginInvoke.
2、Timer.cs
1
using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.Threading;
13
14 namespace ThreadDemo
15 {
16 public partial class Timer: UserControl
17 {
18 public Timer()
19 {
20 InitializeComponent();
21 /// 實例化一個Timer時間器
22 System.Threading.Timer timer = new System.Threading.Timer( new TimerCallback(TimerProc));
23 ///設定500毫秒后啟動,每隔1000毫秒執行一次
24 timer.Change(500, 1000);
25 }
26 int flagnum;
27 public void TimerProc( object state)
28 {
29 /// 在計時器的線程上使用Dispather.BeginInvoke,將計時器線程上的工作委托給UI線程關聯的Dispatcher
30 this.Dispatcher.BeginInvoke( delegate
31 {
32 flagnum++;
33 TextBlock _temptext = new TextBlock();
34 _temptext.Text = flagnum.ToString();
35 timerNum.Children.Add(_temptext);
36 });
37
38
39 }
40 } 41 }
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.Threading;
13
14 namespace ThreadDemo
15 {
16 public partial class Timer: UserControl
17 {
18 public Timer()
19 {
20 InitializeComponent();
21 /// 實例化一個Timer時間器
22 System.Threading.Timer timer = new System.Threading.Timer( new TimerCallback(TimerProc));
23 ///設定500毫秒后啟動,每隔1000毫秒執行一次
24 timer.Change(500, 1000);
25 }
26 int flagnum;
27 public void TimerProc( object state)
28 {
29 /// 在計時器的線程上使用Dispather.BeginInvoke,將計時器線程上的工作委托給UI線程關聯的Dispatcher
30 this.Dispatcher.BeginInvoke( delegate
31 {
32 flagnum++;
33 TextBlock _temptext = new TextBlock();
34 _temptext.Text = flagnum.ToString();
35 timerNum.Children.Add(_temptext);
36 });
37
38
39 }
40 } 41 }
F5運行成功
接下來,我們再用AsyncOperation來實現跨線程訪問。
3、Thread.xaml
1
<
UserControl
x:Class
="ThreadDemo.Thread"
2 xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable ="d"
7 d:DesignHeight ="300" d:DesignWidth ="400" >
8
9 < Grid x:Name ="LayoutRoot" Background ="White" >
10 < ScrollViewer >
11 < StackPanel x:Name ="timerNum" >
12
13 </ StackPanel >
14 </ ScrollViewer >
15 </ Grid > 16 </ UserControl >
2 xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable ="d"
7 d:DesignHeight ="300" d:DesignWidth ="400" >
8
9 < Grid x:Name ="LayoutRoot" Background ="White" >
10 < ScrollViewer >
11 < StackPanel x:Name ="timerNum" >
12
13 </ StackPanel >
14 </ ScrollViewer >
15 </ Grid > 16 </ UserControl >
Thread.cs
1
using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.ComponentModel;
13
14 namespace ThreadDemo
15 {
16 public partial class Thread : UserControl
17 {
18 private AsyncOperation async;
19
20 public Thread()
21 {
22 InitializeComponent();
23 async = AsyncOperationManager.CreateOperation( null);
24 System.Threading.Thread thread = new System.Threading.Thread(TimerProc);
25 thread.Start();
26 }
27
28 public void TimerProc()
29 {
30
31 async.Post(delegate
32 {
33
34 TextBlock _temptext = new TextBlock();
35 _temptext.Text = " 0 ";
36 timerNum.Children.Add(_temptext);
37
38 }, null);
39
40 }
41
42
43 } 44 }
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.ComponentModel;
13
14 namespace ThreadDemo
15 {
16 public partial class Thread : UserControl
17 {
18 private AsyncOperation async;
19
20 public Thread()
21 {
22 InitializeComponent();
23 async = AsyncOperationManager.CreateOperation( null);
24 System.Threading.Thread thread = new System.Threading.Thread(TimerProc);
25 thread.Start();
26 }
27
28 public void TimerProc()
29 {
30
31 async.Post(delegate
32 {
33
34 TextBlock _temptext = new TextBlock();
35 _temptext.Text = " 0 ";
36 timerNum.Children.Add(_temptext);
37
38 }, null);
39
40 }
41
42
43 } 44 }
ok.源碼下載