代码改变世界

C#中的多线程简单应用

2009-01-08 17:10  yufun  阅读(643)  评论(0编辑  收藏  举报

我们有时候需要做一些很耗时间的操作,比如到网络上拿一些数据或者对很多数据进行运算处理,如果是在单线程的程序中,这些运算就会阻塞UI线程,现象就是UI不能响应用户的任何操作,不会刷新。这个时候用户很可能以为程序已经死掉,从而造成很差的用户体验。
解决方法:将很耗时间的运算和处理放在单独的一个线程中进行,UI操作不会受到影响,用户还可以进行其它操作(如果UI中有些操作依赖于当前的的处理,我们可以先将它灰掉,在处理线程结束后再使其可用。更好的是在UI的线程中放一个进度条,来告诉用户当前的处理进度)

在C#中做多线程的处理非常简单:
只需要用代理(Delegate)和跟代理相关的两个函数:
1. BeginInvoke  这个方法将代理指向的方法在一个单独的线程中调用
   使用方法:
     a. 声明一个代理的对象
     b. 用这个代理对象调用BeginInvoke方法         

2. Control.Invoke 这个方法在当前UI的线程空间内调用代理所指向的方法
    使用方法:
      a. 声明一个代理对象
      b. 调用控件的Invoke方法(一般在WinForm程序中,可以调用this.Invoke方法),将代理对象作为参数传递过去

看代码:

   1: private delegate void LoadPhotosDelegate(SearchParam param);
   2: private void LoadPhotosFromFlickr(SearchParam param)
   3: {
   4:     UpdateUIDelegate updateUI = new UpdateUIDelegate(this.UpdataUI);
   5:     this.Invoke(updateUI);
   6: }
   7:  
   8: private delegate void UpdateUIDelegate();
   9: private void UpdataUI()
  10: {
  11:     //进行UI的更新操作,比如更新进度条,显示图片等
  12: }
  13:  
  14: private void SearchPhoto(SearchParam param)
  15: {
  16:     LoadPhotosDelegate loadPhotos = new LoadPhotosDelegate(LoadPhotosFromFlickr);
  17:     loadPhotos.BeginInvoke(param, null, null);
  18: }