【多线程系列--ManualResetEvent2】

1、转:http://www.cnblogs.com/fangzheng/archive/2010/06/07/1750205.html

航班数据获取系统的使命是:在每天的指定时刻去网站抓取数据。当系统开始运行后,将无人看管。因此系统的关键在于两点:一是由于数据量巨大,需要开10个线程去获取数据。二是线程要循环获取数据,保证每一天的指定时刻都会开始获取数据。关键点1在文章lock在多线程中的应用已经完成。故本篇主要完成关键点2。之前在线程的循环问题上徘徊良久,不得其中奥妙。如今,将自己所思所得,与尔等分享,以期共同进步。

  碰到的问题有这么2个:

  1、当线程start()之后,便不能再start()。

  解决方法:等线程运行完成,自行结束,然后重新新建线程。

  2、使用suspend()、resume(),被.net告知,已过时,请用信号量机制。不得已,学习ManualResetEvent()。发现,确实能很方便地解决问题,简单极了。

  首先,明确概念:ManualResetEvent是线程同步事件,用来通知1个或多个线程 。

  其次,明确三个重要方法:

  1)Set(),将事件状态设为终止,允许1个或多个线程继续。

  2)ReSet(),将事件状态设为非终止,导致1个或多个线程阴止。

  3)WaitOne(),阻止当前线程,直到当前ManualResetEvent收到信号。

 

  四个按钮:开始、暂停、继续、退出

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OracleClient;
using System.Net;
using System.Threading;
using System.Collections;

namespace DataManage
{
     public  partial  class FlightGet : Form
    {
         public DataTable dt;
         public  string sConnectionString = System.Configuration.ConfigurationSettings.AppSettings[ " ConnectionString "].ToString();
         public Thread tGet; // 获取所有AIRLINE的线程
         public Thread tCompare; // 指定时间的线程
         public Thread tGetHtml1; // 获取网页线程1
         public Thread tGetHtml2; // 获取网页线程2
         public Thread tGetHtml3; // 获取网页线程3
         public Thread tGetHtml4; // 获取网页线程4
         public Thread tGetHtml5; // 获取网页线程5
         public Thread tGetHtml6; // 获取网页线程6
         public Thread tGetHtml7; // 获取网页线程7
         public Thread tGetHtml8; // 获取网页线程8
         public Thread tGetHtml9; // 获取网页线程9
         public Thread tGetHtml10; // 获取网页线程10
         public Hashtable parm;
         public  string targetURL;
         public  int currcount =  0;
        DataRow newrow;
        System.Object obj =  new  object(); // 用于lock的对象
         object objCmd =  new  object();
         public  delegate  void AddTxt(); // 定义UI更新代理
         public  delegate  void dTxt( int iNum); // 更新进度条及航线数量代理
         public  delegate  void dTime( string sTime); // 更新时间的代理
         public  delegate  void dSetButton( bool sTag); // 更新按钮的可用
         bool bPauseTag =  false; // 暂停标志
         public ManualResetEvent mBegin =  new ManualResetEvent( false);
         public FlightGet()
        {
            InitializeComponent();
            SetButtonStart( true);
            SetButtonPause( false);
            SetButtonContinue( false);
        }
         // 当前航班
         public  void Writting( int iNum)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTxt(Writting), iNum);
            }
             else
            {
                 this.tb_flight1.Text = iNum.ToString();
            }
        }
         // 剩余航班
         public  void LeaveFlight( int iNum)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTxt(LeaveFlight), iNum);
            }
             else
            {
                 this.tb_flight2.Text = iNum.ToString();
            }
        }
         // 所用时间
         public  void UseTime( string sTime)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTime(UseTime), sTime);
            }
             else
            {
                 this.tb_time1.Text = sTime;
            }
        }
         // 剩余时间
         public  void LeaveTime( string sTime)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTime(LeaveTime), sTime);
            }
             else
            {
                 this.tb_time2.Text = sTime;
            }
        }
         // 进度条过程值
         public  void SetBar( int iNum)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTxt(SetBar), iNum);
            }
             else
            {
                 this.bar.Value = iNum;
            }
        }
         // 进度条开始值
         public  void SetBarMin( int iNum)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTxt(SetBarMin), iNum);
            }
             else
            {
                 this.bar.Minimum = iNum;
            }
        }
         // 进度条最大值
         public  void SetBarMax( int iNum)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTxt(SetBarMax), iNum);
            }
             else
            {
                 this.bar.Maximum = iNum;
            }
        }
         // 进度
         public  void SetRate( string sTime)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dTime(SetRate), sTime);
            }
             else
            {
                 this.l_rate.Text = sTime;
            }
        }
         // 开始按钮
         public  void SetButtonStart( bool sTag)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dSetButton(SetButtonStart), sTag);
            }
             else
            {
                 this.btn_start.Enabled = sTag;
            }
        }
         // 暂停按钮
         public  void SetButtonPause( bool sTag)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dSetButton(SetButtonPause), sTag);
            }
             else
            {
                 this.btn_pause.Enabled = sTag;
            }
        }
         // 继续按钮
         public  void SetButtonContinue( bool sTag)
        {
             if ( this.InvokeRequired)
            {
                 this.BeginInvoke( new dSetButton(SetButtonContinue), sTag);
            }
             else
            {
                 this.btn_continue.Enabled = sTag;
            }
        }
        
        
         private  void btn_start_Click( object sender, EventArgs e)
        {
            SetButtonStart( false);
            SetButtonPause( false);
            SetButtonContinue( false);

            tCompare =  new Thread( new ThreadStart(compare));
            tCompare.IsBackground =  true;
            tCompare.Start();
        }
         // 暂停
         private  void btn_pause_Click( object sender, EventArgs e)
        {
            SetButtonPause( false);
            SetButtonContinue( true);
            mBegin.Reset(); // 阻止所有线程
        }
        // 继续
         private  void btn_continue_Click( object sender, EventArgs e)
        {
            SetButtonPause( true);
            SetButtonContinue( false);
            mBegin.Set(); // 继续所有线程

        }
         // 退出
         private  void btn_exit_Click( object sender, EventArgs e)
        {     
             this.Close();
        }
         // 比对时间,无穷地比对
         public  void compare()
        {
             while ( 1 ==  1)
            {
                Application.DoEvents();
                System.DateTime currentTime =  new System.DateTime();
                currentTime = System.DateTime.Now;
                 int iHour = currentTime.Hour; // 当前 时
                 int iMinute = currentTime.Minute; // 当前 分 
                 int iSecond = currentTime.Second; //  当前 秒

                 int xHour =  int.Parse(tb_hour.Text); // 设定 时
                 int xMinute =  int.Parse(tb_minute.Text); // 设定 分
                 int xSecond =  int.Parse(tb_second.Text); // 设定 秒
                 if (iHour == xHour && iMinute == xMinute && iSecond == xSecond) // 到达指定时间,启动10个线程
                {
                    Thread.Sleep( 2000);
                    currcount =  0; // 从第一行开始获取
                    SetButtonContinue( true);
                    SetButtonPause( true);
                    
                    tGetHtml1 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml1.IsBackground =  true;
                    tGetHtml1.Start();

                    tGetHtml2 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml2.IsBackground =  true;
                    tGetHtml2.Start();

                    tGetHtml3 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml3.IsBackground =  true;
                    tGetHtml3.Start();

                    tGetHtml4 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml4.IsBackground =  true;
                    tGetHtml4.Start();

                    tGetHtml5 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml5.IsBackground =  true;
                    tGetHtml5.Start();

                    tGetHtml6 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml6.IsBackground =  true;
                    tGetHtml6.Start();

                    tGetHtml7 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml7.IsBackground =  true;
                    tGetHtml7.Start();

                    tGetHtml8 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml8.IsBackground =  true;
                    tGetHtml8.Start();

                    tGetHtml9 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml9.IsBackground =  true;
                    tGetHtml9.Start();

                    tGetHtml10 =  new Thread( new ThreadStart(GetHtml));
                    tGetHtml10.IsBackground =  true;
                    tGetHtml10.Start();

                    mBegin.Set(); // 给出信号
                    
                }
                 else
                {
                    Thread.Sleep( 1000);
                     continue;
                }
            }
        }
         public  void GetHtml()
        {
            mBegin.WaitOne();

             int iCountRows = dt.Rows.Count;
             bool flag =  false;
             while ( true)
            {
                mBegin.WaitOne(); // 为暂停功能而设
                     lock (obj)
                    {
                         if (currcount < iCountRows) 
                        {
                            newrow = dt.Rows[currcount];
                            currcount = currcount +  1;
                            flag =  true;
                        }
                         else
                        {
                            SetButtonPause( false);
                            SetButtonContinue( false);
                            flag =  false;
                        }
                         if (flag ==  false)
                        {
                             break; // 跳出while循环,10个线程依次终止
                        }
                    }
                    
                     for ( int j =  0; j <  int.Parse(tb_dates.Text); j++)
                    {
                        mBegin.WaitOne(); // 为暂停功能而设
                        
// 获取网页字符串
                        WebClient wc =  new WebClient();
                        byte[] myDataBuffer = wc.DownloadData(targetURL);
                        string s = System.Text.ASCIIEncoding.Default.GetString(myDataBuffer);
                         ………… // 获取数据
                    }   
            }   
        }

         private  void FlightGet_FormClosing( object sender, FormClosingEventArgs e)
        {
             if (MessageBox.Show( " 确定关闭? "" 关闭确认 ", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
            {
                e.Cancel =  true;
            }
             else
            {
                 if (tCompare.IsAlive)
                {
                    tCompare.Abort();
                }
                 if (tGetHtml1!= null && tGetHtml1.IsAlive)
                {
                    tGetHtml1.Abort();
                }
                 if (tGetHtml2!= null && tGetHtml2.IsAlive)
                {
                    tGetHtml2.Abort();
                }
                 if (tGetHtml3!= null && tGetHtml3.IsAlive)
                {
                    tGetHtml3.Abort();
                }
                 if (tGetHtml4!= null && tGetHtml4.IsAlive)
                {
                    tGetHtml4.Abort();
                }
                 if (tGetHtml5!= null && tGetHtml5.IsAlive)
                {
                    tGetHtml5.Abort();
                }
                 if (tGetHtml6!= null&& tGetHtml6.IsAlive)
                {
                    tGetHtml6.Abort();
                }
                 if (tGetHtml7 != null && tGetHtml7.IsAlive)
                {
                    tGetHtml7.Abort();
                }
                 if (tGetHtml8 != null && tGetHtml8.IsAlive)
                {
                    tGetHtml8.Abort();
                }
                 if (tGetHtml9!= null && tGetHtml9.IsAlive)
                {
                    tGetHtml9.Abort();
                }
                 if (tGetHtml10 != null && tGetHtml10.IsAlive)
                {
                    tGetHtml10.Abort();
                }
            }
        }
       

    }
}

 

你可能感兴趣的:(event)