多线程采集器的核心代码

自己写的一个采集程序,用来采集小说,将线程控制的代码发出来。

通过采集的数据数量来分配线程数,可以限制最大线程数量

采集数据采取自动分配的方式,为每个线程平均分配一定量的采集任务,具体采集部分用WebClient或者其他方式都可

ManualResetEvent 用来控制线程的挂起和恢复

通过建立委托来实现进度条的刷新和控件提示文本的刷新

 

  1  using System;
  2  using System.Collections.Generic;
  3  using System.Drawing;
  4  using System.Windows.Forms;
  5 
  6  using System.Threading;
  7  using System.Text.RegularExpressions;
  8 
  9  namespace GUIDemo
 10 {
 11      public  partial  class MainForm : Form
 12     {
 13          public MainForm()
 14         {
 15             InitializeComponent();
 16         }
 17         
 18         ManualResetEvent  mReset =  new ManualResetEvent( true);
 19         
 20         List<Thread> threads =  new List<Thread>();
 21         
 22          void BtnStartClick( object sender, EventArgs e)
 23         {
 24              if(workStatus == WorkStatus.Pause)
 25             {
 26                  if(threads.Count> 0)
 27                 {
 28                     mReset.Set();
 29                 }
 30                 workStatus = WorkStatus.Working;
 31                 SetButtonStatus();
 32                  return;
 33             }
 34             
 35             workStatus = WorkStatus.Working;
 36             SetButtonStatus();
 37             
 38             List<ALink> links =  new List<ALink>();
 39             
 40              for( int i= 0;i< 76;i++)
 41             {
 42                 links.Add( new ALink(i.ToString()));
 43             }
 44             
 45             progressBar1.Maximum =  76;
 46             progressBar1.Value =  0;
 47             th_cnt =  0;
 48             
 49              int dataCount = links.Count;
 50              int perCount =  25;
 51             
 52              int threadCount = dataCount % perCount == 0? dataCount/perCount:dataCount/perCount+ 1;
 53             
 54              int limitCount =  3;
 55              // 限制最大线程数量
 56               if(threadCount>limitCount)
 57             {
 58                 threadCount = limitCount;
 59                 perCount = dataCount % threadCount== 0?dataCount/threadCount:dataCount/threadCount+ 1;
 60             }
 61             
 62              int cnt =  0int i_cnt= 0;
 63             
 64             List<ALink> perLinks =  new List<ALink>();
 65              // 分配资源
 66               foreach(ALink link  in links)
 67             {
 68                  if(cnt%perCount== 0&&cnt> 0)
 69                 {
 70                     Thread thread =  new Thread( new ParameterizedThreadStart(DoWork));
 71                     thread.Name =  " thread "+i_cnt.ToString();
 72                     thread.Start(Clone(perLinks));
 73                     threads.Add(thread);
 74                     i_cnt++;
 75                     perLinks.Clear();
 76                 }
 77                 perLinks.Add(link);
 78                 cnt++;
 79             }
 80             
 81              if(perLinks.Count> 0&&i_cnt<threadCount)
 82             {
 83                 Thread thread =  new Thread( new ParameterizedThreadStart(DoWork));
 84                 thread.Name =  " thread "+i_cnt.ToString();
 85                 thread.Start(Clone(perLinks));
 86                 threads.Add(thread);
 87                 i_cnt++;
 88                 perLinks.Clear();
 89             }
 90             
 91              // Thread.Sleep(1000);
 92               // flagExit = true;
 93          }
 94         
 95          public  static  bool flagExit =  false;
 96         
 97          static  object locker =  new  object();
 98         
 99          static  int th_cnt =  0;
100         
101          void DoWork( object threadParam)
102         {
103             List<ALink> items = threadParam  as List<ALink>;
104              foreach (ALink link  in items.ToArray())
105             {
106                 mReset.WaitOne();
107                  if(flagExit)  break;
108                  lock (locker) {
109                     th_cnt++;
110                     UpdateProcess(th_cnt);
111                 }
112                 OutputText(Thread.CurrentThread.Name+ " : "+link.Url);
113                 ShowText(link.Url);
114                 
115                 Thread.Sleep( 50);
116             }
117              if(flagExit)
118             {
119                 OutputText(Thread.CurrentThread.Name+ " :exit ");
120             } else{
121                 OutputText(Thread.CurrentThread.Name+ " :finlished ");
122             }
123             OutputText(th_cnt.ToString());
124         }
125         
126          delegate  void ControlHandler( string text);
127          delegate  void ProcessBarHandler( int i);
128         
129          void ShowText( string text)
130         {
131              if(!label1.InvokeRequired)
132             {
133                 label1.Text = text;
134             }
135              else
136             {
137                 ControlHandler show =  new ControlHandler(ShowText);
138                 BeginInvoke(show, new  object[]{text});
139             }
140         }
141         
142          void UpdateProcess( int i)
143         {
144              if(!progressBar1.InvokeRequired)
145             {
146                 progressBar1.Value = i>progressBar1.Maximum ? progressBar1.Maximum:i;
147             }
148              else
149             {
150                 ProcessBarHandler show =  new ProcessBarHandler(UpdateProcess);
151                 BeginInvoke(show, new  object[]{i});
152             }
153         }
154         
155          static List<T> Clone<T>(IEnumerable<T> oldList) 
156         {     
157              return  new List<T>(oldList); 
158         }
159         
160          void OutputText( string text)
161         {
162             System.Diagnostics.Debug.WriteLine(text);
163         }
164         
165          void ReleaseThread()
166         {
167              if(threads.Count> 0)
168             {
169                  foreach(Thread th  in threads)
170                 {
171                     th.Abort();
172                 }
173                 threads.Clear();
174             }
175         }
176         
177          void MainFormFormClosing( object sender, FormClosingEventArgs e)
178         {
179             ReleaseThread();
180         }
181         
182          void BtnStopClick( object sender, EventArgs e)
183         {
184              if(workStatus== WorkStatus.Working || workStatus== WorkStatus.Pause)
185             {
186                 ReleaseThread();
187                 
188                 progressBar1.Value =  0;
189                 progressBar1.Refresh();
190                 
191                 th_cnt =  0;
192                 
193                 workStatus = WorkStatus.Stop;
194                 SetButtonStatus();
195             }
196         }
197         
198         WorkStatus workStatus = WorkStatus.Waitting;
199         
200          void BtnPauseClick( object sender, EventArgs e)
201         {
202              if(workStatus == WorkStatus.Working)
203             {
204                  if(threads.Count> 0)
205                 {
206                     mReset.Reset();
207                     workStatus = WorkStatus.Pause;
208                     SetButtonStatus();
209                 }
210             }
211         }
212         
213          void SetButtonStatus()
214         {
215              switch(workStatus)
216             {
217                  case WorkStatus.Working:
218                     btnStart.Enabled =  false;
219                     btnPause.Enabled =  true;
220                     btnStop.Enabled =  true;
221                      break;
222                  case WorkStatus.Pause:
223                     btnStart.Enabled =  true;
224                     btnPause.Enabled =  false;
225                     btnStop.Enabled =  true;
226                      break;
227                  case WorkStatus.Stop:
228                     btnStart.Enabled =  true;
229                     btnPause.Enabled =  false;
230                     btnStop.Enabled =  false;
231                      break;
232                  case WorkStatus.Waitting:
233                     btnStart.Enabled =  true;
234                     btnPause.Enabled =  false;
235                     btnStop.Enabled =  false;
236                      break;        
237             }
238         }
239         
240          void MainFormLoad( object sender, EventArgs e)
241         {
242             SetButtonStatus();
243         }
244     }
245     
246      public  class ALink
247     {
248          public  string Url= "";
249          public ALink( string url)
250         {
251              this.Url = url;
252         }
253     }
254     
255      enum WorkStatus
256     {
257         Pause,Stop,Working,Waitting
258     }
259 }

 

你可能感兴趣的:(多线程)