C#中的线程

by:Alex Fr  译:adaiye


简介

.NET框架提供很多方法来实现多线程编程。我想展示如何通过同步访问用户接口去运行一个工作线程(例如,一个读取记录集并要在一个窗体中填充控件的线程)。
运行线程,我用:
  • 线程实例和主线程函数
  • 两个使线程停止的事件。第一个事件是设置何时主线程想停止工作线程,第二个事件是工作线程设置何时想真正停止。
.NET只允许Control中创建的线程去调用 System.Windows.Forms.Control的函数。要想从另一个线程中访问 System.Windows.Forms.Control中的函数,你需要使用 Control.Invoke(同步调用)或 Control.BeginInvoke(异步调用)函数。比如说显示数据库的记录,我们就需要 Invoke
要想实现这个,我们要用:
  • 一个为了访问窗体的委托类型。委托实例和函数调用使用这个委托。
  • 从工作线程来的函数调用。
下一个问题是准确的停止工作线程。做这些的步骤是:
  • 启动“停止线程”事件;
  • 等待“线程已经停止”事件;
  • Application.DoEvents函数等待事件处理消息。这是为了防止死锁的,因为工作线程的Invoke调用是被主线程所处理的。
线程函数检查每个迭代,看“停止线程”事件是否发生了。如果这个事件发生了,函数调用清理操作,触发“线程已经停止”事件,并返回。
Demo有两个类: MainForm和 LongProcessLongProcess.Run函数在线程中被执行,它会用几行数据来填充列表。工作线程可能会自然停止,或者当用户按下 "Stop Thread"按钮或关闭窗体时停止。

源代码


  1  //  MainForm.cs
  2 
  3  namespace  WorkerThread
  4  {
  5       //  delegates used to call MainForm functions from worker thread
  6       public   delegate   void  DelegateAddString(String s);
  7       public   delegate   void  DelegateThreadFinished();
  8 
  9       public   class  MainForm : System.Windows.Forms.Form
 10      {
 11           //  
 12 
 13           //  worker thread
 14          Thread m_WorkerThread;
 15 
 16           //  events used to stop worker thread
 17          ManualResetEvent m_EventStopThread;
 18          ManualResetEvent m_EventThreadStopped;
 19 
 20           //  Delegate instances used to call user interface functions 
 21           //  from worker thread:
 22           public  DelegateAddString m_DelegateAddString;
 23           public  DelegateThreadFinished m_DelegateThreadFinished;
 24 
 25           //  
 26 
 27           public  MainForm()
 28          {
 29              InitializeComponent();
 30 
 31               //  initialize delegates
 32              m_DelegateAddString  =   new  DelegateAddString( this .AddString);
 33              m_DelegateThreadFinished  =   new  DelegateThreadFinished( this .ThreadFinished);
 34 
 35               //  initialize events
 36              m_EventStopThread  =   new  ManualResetEvent( false );
 37              m_EventThreadStopped  =   new  ManualResetEvent( false );
 38 
 39          }
 40 
 41           //  
 42 
 43           //  Start thread button is pressed
 44           private   void  btnStartThread_Click( object  sender, System.EventArgs e)
 45          {
 46               //  
 47              
 48               //  reset events
 49              m_EventStopThread.Reset();
 50              m_EventThreadStopped.Reset();
 51 
 52               //  create worker thread instance
 53              m_WorkerThread  =   new  Thread( new  ThreadStart( this .WorkerThreadFunction));
 54 
 55              m_WorkerThread.Name  =   " Worker Thread Sample " ;    //  looks nice in Output window
 56 
 57              m_WorkerThread.Start();
 58 
 59          }
 60 
 61 
 62           //  Worker thread function.
 63           //  Called indirectly from btnStartThread_Click
 64           private   void  WorkerThreadFunction()
 65          {
 66              LongProcess longProcess;
 67 
 68              longProcess  =   new  LongProcess(m_EventStopThread, m_EventThreadStopped,  this );
 69 
 70              longProcess.Run();
 71          }
 72 
 73           //  Stop worker thread if it is running.
 74           //  Called when user presses Stop button or form is closed.
 75           private   void  StopThread()
 76          {
 77               if  ( m_WorkerThread  !=   null    &&   m_WorkerThread.IsAlive )   //  thread is active
 78              {
 79                   //  set event "Stop"
 80                  m_EventStopThread.Set();
 81 
 82                   //  wait when thread  will stop or finish
 83                   while  (m_WorkerThread.IsAlive)
 84                  {
 85                       //  We cannot use here infinite wait because our thread
 86                       //  makes syncronous calls to main form, this will cause deadlock.
 87                       //  Instead of this we wait for event some appropriate time
 88                       //  (and by the way give time to worker thread) and
 89                       //  process events. These events may contain Invoke calls.
 90                       if  ( WaitHandle.WaitAll(
 91                          ( new  ManualResetEvent[] {m_EventThreadStopped}), 
 92                           100 ,
 93                           true ) )
 94                      {
 95                           break ;
 96                      }
 97 
 98                      Application.DoEvents();
 99                  }
100              }
101          }
102 
103           //  Add string to list box.
104           //  Called from worker thread using delegate and Control.Invoke
105           private   void  AddString(String s)
106          {
107              listBox1.Items.Add(s);
108          }
109 
110           //  Set initial state of controls.
111           //  Called from worker thread using delegate and Control.Invoke
112           private   void  ThreadFinished()
113          {
114              btnStartThread.Enabled  =   true ;
115              btnStopThread.Enabled  =   false ;
116          }
117 
118      }
119  }
120 
121  //  LongProcess.cs
122 
123  namespace  WorkerThread
124  {
125       public   class  LongProcess
126      {
127           //  
128      
129           //  Function runs in worker thread and emulates long process.
130           public   void  Run()
131          {
132               int  i;
133              String s;
134 
135               for  (i  =   1 ; i  <=   10 ; i ++ )
136              {
137                   //  make step
138                  s  =   " Step number  "   +  i.ToString()  +   "  executed " ;
139 
140                  Thread.Sleep( 400 );
141 
142                   //  Make synchronous call to main form.
143                   //  MainForm.AddString function runs in main thread.
144                   //  (To make asynchronous call use BeginInvoke)
145                  m_form.Invoke(m_form.m_DelegateAddString,  new  Object[] {s});
146 
147 
148                   //  check if thread is cancelled
149                   if  ( m_EventStop.WaitOne( 0 true ) )
150                  {
151                       //  clean-up operations may be placed here
152                       //  
153 
154                       //  inform main thread that this thread stopped
155                      m_EventStopped.Set();
156 
157                       return ;
158                  }
159              }
160 
161               //  Make synchronous call to main form
162               //  to inform it that thread finished
163              m_form.Invoke(m_form.m_DelegateThreadFinished,  null );
164          }
165 
166      }
167  }
168 
169 
170 
171 
172 

转载于:https://www.cnblogs.com/adaiye/archive/2007/10/03/913214.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值