Silverlight 4中四种多线程编程技术

Silverlight 4中四种多线程编程技术,第1张

概述Silverlight 4中四种多线程编程技术 时间:2011-05-16 05:35来源:IT168 作者:朱先忠 1.使用WaitHandle   等待句柄应当是你进行多线程编程的必备装备。由于我们的主要兴趣点在于Silverlight多线程编程相关的内容,所以我们不想再深入探讨WaitHandle。但在此为你提供一个典型的例子,告诉你使用WaitHandle的基本方法。   清单1: 以下是 Silverlight 4中四种多线程编程技术

时间:2011-05-16 05:35来源:IT168 作者:朱先忠

@H_403_29@ 1.使用WaitHandle

@H_403_29@   等待句柄应当是你进行多线程编程的必备装备。由于我们的主要兴趣点在于Silverlight多线程编程相关的内容,所以我们不想再深入探讨WaitHandle。但在此为你提供一个典型的例子,告诉你使用WaitHandle的基本方法。

@H_403_29@   清单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(); 
  } 
  }
@H_403_29@  

@H_403_29@   2.使用定时器

@H_403_29@   System.Thread.Timer是一个多线程的计时器。这是一个简单的轻量级的计时器,使用回调方法,并由线程池中线程提供相应的服务。让我们看一个相关的例子:

@H_403_29@   清单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() + "\r\n"; 
  _timer = new System.Threading.Timer(MyTimerCallback,"helltimer",3000,1000); 
  } 
  private voID MyTimerCallback(object state) 
  { 
  string result = string.Format("{0} - {1}: \r\n",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(); 
  } 
  } 
  }
@H_403_29@  

@H_403_29@   有以下几点值得注意。

@H_403_29@   第一,明确传递给定时器的参数:方法MyTimerCallback表示在线程池中执行的方法。第二个参数(在本例中的字符串)代表了传递给方法MyTimerCallback的内容。第三个参数详细说明方法MyTimerCallback被调用之前迟延时间的长短,以毫秒为单位。第四个参数是调用MyTimerCallback方法的时间间隔的说明,以毫秒为单位。

@H_403_29@   第二,我们已经使用了SynchronizationContext对象,因为线程上下文是清晰易知的。还要注意,在方法MyTimerCallback中我们调用了它的Post方法来修改UI线程中的内容。最后,通过定时器的Change方法,我们指定在该方法执行5次后,把开始时间设置为五分钟,计时器方法调用的时间间隔为5毫秒。

@H_403_29@   3.使用dispatcherTimer

@H_403_29@   dispatchTimer第一次亮相是在Silverlight(WPF)中作为一个后台线程计时器。与原System.Threading.Timer相比,不同之处在于dispatchTimer是真正的在后台线程中独立执行的,而定时器Timer仍然在UI线程中执行,每隔一个指定的时间接管UI线程的控制权。总体来看,dispatchTimer主要适合于调度任务的情况。在这种情况下,我们可以根据实际要求设置等待时间。请参考下面的示例。

@H_403_29@   清单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(); 
  } 
  }
@H_403_29@  

@H_403_29@   事实上,除StoryBoard组件之外dispatcherTimer也是Silverlight编程中实现动画效果的一种重要技术。当然,我们应该当心使用dispatcherTimer有可能导致创建太多的后台线程,从而有可能导致增加cpu的负荷而降低效率。

@H_403_29@   4.使用BackgrounDWorker

@H_403_29@   System.ComponentModel.BackgrounDWorker首次出现在NET 2.0中,用于简化windows窗体应用程序多线程交互相关的编码过程。现在,它也可用于Silverlight环境中。在后台实现中,BackgrounDWorker使用了dispatcher组件,并把所有多线程相关的复杂内容封装在一个黑盒子中,为您提供最易于使用和现成的解决方案。整体来说,BackgrounDWorker非常适合从事单一的,异步的,并在后台运行的长时间的任务。

@H_403_29@   5.使用.NET Reflector进一步跟踪观察

@H_403_29@   现在,让我们使用.NET Reflector来进一步观察BackgrounDWorker类的内容编码情形。

@H_403_29@   清单4:

以下是代码片段:
    public class BackgrounDWorker 
  { 
  // 事件声明 
  public event DoWorkEventHandler DoWork; 
  public event ProgressChangedEventHandler ProgressChanged; 
  public event RunWorkerCompletedEventHandler RunWorkerCompleted; 
  // 方法声明 
  public BackgrounDWorker(); 
  public voID CancelAsync(); 
  protected virtual voID OnDoWork(DoWorkEventArgs e); 
  protected virtual voID OnProgressChanged(ProgressChangedEventArgs e); 
  protected virtual voID OnRunWorkerCompleted(RunWorkerCompletedEventArgs e); 
  public voID ReportProgress(int percentProgress); 
  public voID ReportProgress(int percentProgress,object userState); 
  public voID RunWorkerAsync(); 
  public voID RunWorkerAsync(object argument); 
  // 属性定义 
  public bool CancellationPending { get; } 
  public bool IsBusy { get; } 
  public bool WorkerReportsProgress { get; set; } 
  public bool WorkerSupportsCancellation { get; set; } 
  }
@H_403_29@  

@H_403_29@   从各自的名称来看,你会很容易想象,上面大多成员都是常用的。为了简便起见,我们将不再进行相关的深入分析。但是,我们将构建一个具体的例子,来看一个典型的使用BackgrounDWorker的案例。

@H_403_29@   清单5:

以下是代码片段:
     namespace SilverlightmultiThread 
  { 
  public partial class BackgrounDWorkerTestPage : Page 
  { 
  System.ComponentModel.BackgrounDWorker _backgrounDWorker; 
  public BackgrounDWorkerTestPage() 
  { 
  InitializeComponent(); 
  _backgrounDWorker = new System.ComponentModel.BackgrounDWorker(); 
  _backgrounDWorker.WorkerSupportsCancellation = true; 
  _backgrounDWorker.WorkerReportsProgress = true; 
  _backgrounDWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(_backgrounDWorker_ProgressChanged); 
  _backgrounDWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(_backgrounDWorker_DoWork); 
  _backgrounDWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(_backgrounDWorker_RunWorkerCompleted); 
  } 
  private voID btnStart_Click(object sender,RoutedEventArgs e) 
  { 
  if (!_backgrounDWorker.IsBusy) 
  _backgrounDWorker.RunWorkerAsync("Need Parameter!"); 
  } 
  private voID btnCancel_Click(object sender,RoutedEventArgs e) 
  { 
  if (_backgrounDWorker.WorkerSupportsCancellation) 
  _backgrounDWorker.CancelAsync(); 
  } 
  voID _backgrounDWorker_DoWork(object sender,System.ComponentModel.DoWorkEventArgs e) 
  { 
  for (int i = 0; i < 10; i++) 
  { 
  if ((_backgrounDWorker.CancellationPending == true)) 
  { 
  e.Cancel = true; 
  break; 
  } 
  else 
  { 
  System.Threading.Thread.Sleep(1000); 
  _backgrounDWorker.ReportProgress((i + 1) * 10,i); 
  } 
  } 
  e.Result = "Complete!"; 
  } 
  voID _backgrounDWorker_ProgressChanged(object sender,System.ComponentModel.ProgressChangedEventArgs e) 
  { 
  txtProgress.Text = string.Format("Progress:{0}%; Parameter: {1}", 
  e.Progresspercentage, 
  e.UserState); 
  } 
  voID _backgrounDWorker_RunWorkerCompleted(object sender,System.ComponentModel.RunWorkerCompletedEventArgs e) 
  { 
  if (e.Error != null) 
  { 
  txtMsg.Text += e.Error.ToString() + "\r\n"; 
  } 
  else if (e.Cancelled) 
  { 
  txtMsg.Text += "Cancelled!\r\n"; 
  } 
  else 
  { 
  txtMsg.Text += e.Result.ToString() + "\r\n"; 
  } 
  } 
  } 
  }
@H_403_29@  

@H_403_29@   整体而言,BackgrounDWorker适合运行在一个单独的线程,特别是运行在一个非UI线程上且耗时的 *** 作,以防止用户界面停止响应。上面,我们采用了一个“Cancel”按钮来取消线程的执行—通过判断线程是否可以取消(通过属性WorkerSupportsCancellation)。然后,我们调用方法CancelAsync暂停线程。相应地,该方法RunWorkerAsync用于启动线程,同时传递进可能的需要的参数。正如你所见,真正的异步工作是在方法_backgrounDWorker_DoWork中进行的。同时,它使用ReportProgress方法报告当前进度,另外一个相关的方法_backgrounDWorker_ProgressChanged用于负责在UI线程上呈现这个进度。一旦线程终止或暂停,另外一个相关方法_backgrounDWorker_RunWorkerCompleted即被激活,并输出相关的提示信息。

@H_403_29@ http://www.silverlightchina.net/html/tips/2011/0516/7677.html

总结

以上是内存溢出为你收集整理的Silverlight 4中四种多线程编程技术全部内容,希望文章能够帮你解决Silverlight 4中四种多线程编程技术所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1064271.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)