ManualResetEvent在多线程循环中的应用

 

  航班数据获取系统的使命是:在每天的指定时刻去网站抓取数据。当系统开始运行后,将无人看管。因此系统的关键在于两点:一是由于数据量巨大,需要开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();
                }
            }
        }
       

    }
}

 

 

  

 

 

 

 

 


 

posted on 2010-06-07 13:14  WildFlower  阅读(1341)  评论(0编辑  收藏  举报

导航