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();
}
}
}
}
}