该种多线程的实现方式是利用BackgroundWoker控件对线程操控的方便性,创建多个Form,而在每个Form下是实现功能。我们知道backgroundwoker控件在实现代码功能的时候开启了一个线程,在该线程执行的过程中可以向主线程传递进度等参数。线程执行结束后会调用Complete函数处理收尾的工作。但是当我们需要同时创建多个线程并让他们并发执行,这时显然不能满足需求。那么我们可以单独创建一个Form,该Form的主要作用就是实现你想实现多线程的代码块!然后用在backgroundwoker的doWoker中创建多个Form,其实每一个Form就是一个线程。这样做的好处是便于线程的管理,思路也比较使用system.threading要清晰。当然这种实现方法的操作灵活性和对线程的细致控制还是不能和System.Threading相比的。有不当和错误之处请各位指正!
一下仅列举了部分代码:
1、主界面功能程序
//开始线程
private void ToolStripMenuItemStart_Click(object sender, EventArgs e)
{
menuStripMain.Enabled = false;
toolStripButtonStart.Enabled = false;
toolStripButtonStop.Enabled = true;
toolStripProgressBar1.Value = 0;
toolStripProgressBar1.Maximum = dataGridViewData.Rows.Count;
if (dataGridViewData.Rows.Count != 0)
{
foreach (DataGridViewRow row in dataGridViewData.Rows)
{
SearchThread thread = new FormSearch();
GloableData.Thread.Add(thread);
}
timerThread.Enabled = true;
timerUi.Enabled = true;
}
else
{
MessageBox.Show("没有可以开始的项!");
}
}
private void timerThread_Tick(object sender, EventArgs e)
{
if (GloableData.ThreadCount < 100 && GloableData.ThreadIndex < dataGridViewData.Rows.Count)
{
string[] strArgument = { dataGridViewData.Rows[GloableData.ThreadIndex].Cells[0].Value.ToString(), GloableData.ThreadIndex.ToString() };
dataGridViewData.Rows[GloableData.ThreadIndex].Cells[2].Value = "正在执行";
dataGridViewData.Rows[GloableData.ThreadIndex].Selected = true;
GloableData.Thread[GloableData.ThreadIndex].Search(strArgument);
GloableData.ThreadIndex++;
GloableData.ThreadCount++;
}
else if (GloableData.ThreadIndex == dataGridViewData.Rows.Count)
{
timerThread.Enabled = false;
}
}
private void timerUi_Tick(object sender, EventArgs e)
{
if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum)
{
timerUi.Enabled = false;
menuStripMain.Enabled = true;
toolStripButtonStart.Enabled = true;
toolStripButtonStop.Enabled = true;
}
dataGridViewData.Rows[GloableData.ProgressMessage[0]].Cells[1].Value = GloableData.ProgressMessage[1];
lock (new object())
{
foreach (int index in GloableData.Progress)
{
toolStripProgressBar1.Value++;
dataGridViewData.Rows[index].Cells[2].Value = "完成";
dataGridViewData.Rows[index].Selected = false;
dataGridViewData.Rows[index].Cells[1].Value = 100;
}
GloableData.Progress.Clear();
}
Application.DoEvents();
}
2、FormSearch的模板
public void Search(string[] strArgument)
{
backgroundWorker1.RunWorkerAsync(strArgument);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string[] argument = (string[])e.Argument;
GetCarData getData = new GetCarData();
getData.ProxyManager = GloableData.ProxyManager;
int totalCount = 0;
//取第一页的数据
int i = 1, j = 0,count = 0;
e.Result = argument[1];
do
{
List<string> value = new List<string>();
MatchCollection strJson = getData.Search(i, argument[0], out totalCount);
if (strJson != null)
{
foreach (Match json in strJson)
{
backgroundWorker1.WorkerSupportsCancellation = GloableData.StopFlag;
if (json != null)
{
string result = getData.CarData(json);
if(result != "")
{
string data = getData.JsonToDataTable(argument[0],result);
if (data != "")
{
value.Add(data);
}
}
}
else if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
j++;
backgroundWorker1.ReportProgress((j * 100 / totalCount), argument[1]);
}
//计算分页数目
count = (int)Math.Ceiling((double)totalCount / (double)300);
i++;
lock (new object())
{
DBControl.InsertIntoAccess(value);
}
}
} while (i <= count);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
lock (new object())
{
GloableData.ProgressMessage[0] = Convert.ToInt32((string)e.UserState);
GloableData.ProgressMessage[1] = e.ProgressPercentage;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (GloableData.ThreadCount > 0)
{
GloableData.ThreadCount--;
}
lock (new object())
{
GloableData.Progress.Add(Convert.ToInt32((string)e.Result));
}
}
}