在上篇文章中,我们介绍了Silverlight 4编程环境下的五种多线程编程技巧。在本篇中,我们将介绍另外四种Silverlight 4多线程编程中的支持技术。
1.使用WaitHandle
等待句柄应当是你进行多线程编程的必备装备。由于我们的主要兴趣点在于Silverlight多线程编程相关的内容,所以我们不想再深入探讨WaitHandle。但在此为你提供一个典型的例子,告诉你使用WaitHandle的基本方法。
清单1:
public partial class MainPage : UserControl
AutoResetEvent handle = new AutoResetEvent(true);
public MainPage()
INItializeComponent();
new Thread(() =>
while (true)
handle.WaitOne();
this.Dispatcher.BeginInvoke(() =>
this.TextBlock1.Text = DateTime.Now.ToString();
});
}).Start();
private void Button_Click(object sender, RoutedEventArgs e)
handle.Set();
2.使用定时器
System.Thread.Timer是一个多线程的计时器。这是一个简单的轻量级的计时器,使用回调方法,并由线程池中线程提供相应的服务。让我们看一个相关的例子:
清单2:(参考示例页面TimerTestPage.xaml)
namesPACe SilverlightMultiThread
public partial class TimerTestPage : Page
System.Threading.SynchronizationContext _syncContext;
System.Threading.Timer _timer;
private int _flag = 0;
public TimerTestPage()
InitializeComponent();
//UI线程
_syncContext = System.Threading.SynchronizationContext.Current;
//输出当前时间
txtMsg.Text = DateTime.Now.ToString() + rn;
_timer = new System.Threading.Timer(MyTimerCallback, helltimer, 3000, 1000);
private void MyTimerCallback(object state)
string result = string.Format({0} - {1}: rn, DateTime.Now.ToString(), (string)state);
_syncContext.Post(delegate { txtMsg.Text += result; }, null);
_flag++;
if (_flag == 5)
_timer.Change(5000, 500);
else if (_flag == 10)
_timer.Dispose();
有以下几点值得注意。
第一,明确传递给定时器的参数:方法MyTimerCallback表示在线程池中执行的方法。第二个参数(在本例中的字符串)代表了传递给方法MyTimerCallback的内容。第三个参数详细说明方法MyTimerCallback被调用之前迟延时间的长短,以毫秒为单位。第四个参数是调用MyTimerCallback方法的时间间隔的说明,以毫秒为单位。
第二,我们已经使用了SynchronizationContext对象,因为线程上下文是清晰易知的。还要注意,在方法MyTimerCallback中我们调用了它的Post方法来修改UI线程中的内容。最后,通过定时器的Change方法,我们指定在该方法执行5次后,把开始时间设置为五分钟,计时器方法调用的时间间隔为5毫秒。
3.使用DispatcherTimer
DispatchTimer第一次亮相是在Silverlight(WPF)中作为一个后台线程计时器。与原System.Threading.Timer相比,不同之处在于DispatchTimer是真正的在后台线程中独立执行的,而定时器Timer仍然在UI线程中执行,每隔一个指定的时间接管UI线程的控制权。总体来看,DispatchTimer主要适合于调度任务的情况。在这种情况下,我们可以根据实际要求设置等待时间。请参考下面的示例。
清单3:
public partial class MainPage : UserControl
DispatcherTimer timer;
public MainPage()
InitializeComponent();
timer = new DispatcherTimer();
timer.Tick += (s, e) => {
//每隔1000毫秒发生一次
//修改UI线程中的对象
this.TextBlock1.Text = DateTime.Now.ToString();
};
timer.Interval = TimeSpan.FromMilliseconds(1000);
timer.Start();
事实上,除StoryBoard组件之外dispatcherTimer也是Silverlight编程中实现动画效果的一种重要技术。当然,我们应该当心使用dispatcherTimer有可能导致创建太多的后台线程,从而有可能导致增加CPU的负荷而降低效率。
4.使用BackgroundWorker
System.ComponentModel.BackgroundWorker首次出现在NET 2.0中,用于简化Windows窗体应用程序多线程交互相关的编码过程。现在,它也可用于Silverlight环境中。在后台实现中,BackgroundWorker使用了Dispatcher组件,并把所有多线程相关的复杂内容封装在一个黑盒子中,为您提供最易于使用和现成的解决方案。整体来说,BackgroundWorker非常适合从事单一的,异步的,并在后台运行的长时间的任务。
5.使用.NET Reflector进一步跟踪观察
现在,让我们使用.NET Reflector来进一步观察BackgroundWorker类的内容编码情形。




