在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
>
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();
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 }
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
>
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 }
ok.源码下载