这是我有两名背景工作者的背景工作者。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;
using System.Net;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;
namespace GatherLinks
{
class BackgroundWebCrawling
{
public string f;
int counter = 0;
List<string> WebSitesToCrawl;
int MaxSimultaneousThreads;
public BackgroundWorker mainBackGroundWorker;
BackgroundWorker secondryBackGroundWorker;
WebcrawlerConfiguration webcrawlerCFG;
List<WebCrawler> webcrawlers;
int maxlevels;
public event EventHandler<BackgroundWebCrawlingProgressEventHandler> ProgressEvent;
ManualResetEvent _busy = new ManualResetEvent(true);
public BackgroundWebCrawling()
{
webcrawlers = new List<WebCrawler>();
mainBackGroundWorker = new BackgroundWorker();
mainBackGroundWorker.WorkerSupportsCancellation = true;
mainBackGroundWorker.DoWork += mainBackGroundWorker_DoWork;
}
private void mainBackGroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 0; i < WebSitesToCrawl.Count; i++)
{
_busy.WaitOne();
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
while (counter >= MaxSimultaneousThreads)
{
Thread.Sleep(10);
}
WebCrawler wc = new WebCrawler(webcrawlerCFG);
webcrawlers.Add(wc);
counter++;
secondryBackGroundWorker = new BackgroundWorker();
secondryBackGroundWorker.DoWork += secondryBackGroundWorker_DoWork;
object[] args = new object[] { wc, WebSitesToCrawl[i] };
secondryBackGroundWorker.RunWorkerAsync(args);
}
while (counter > 0)
{
Thread.Sleep(10);
}
}
catch
{
MessageBox.Show("err");
}
}
private void secondryBackGroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
object[] args = (object[])e.Argument;
WebCrawler wc = (WebCrawler)args[0];
string mainUrl = (string)args[1];
wc.ProgressEvent += new EventHandler<WebCrawler.WebCrawlerProgressEventHandler>(x_ProgressEvent);
wc.webCrawler(mainUrl, maxlevels);
counter--;
}
catch
{
MessageBox.Show("err");
}
}
public void Start(List<string> sitestocrawl, int threadsNumber, int maxlevels, WebcrawlerConfiguration wccfg)
{
this.maxlevels = maxlevels;
webcrawlerCFG = wccfg;
WebSitesToCrawl = sitestocrawl;
MaxSimultaneousThreads = threadsNumber;
mainBackGroundWorker.RunWorkerAsync();
}
private void x_ProgressEvent(object sender, WebCrawler.WebCrawlerProgressEventHandler e)
{
Object[] temp_arr = new Object[8];
temp_arr[0] = e.csFiles;
temp_arr[1] = e.mainUrl;
temp_arr[2] = e.levels;
temp_arr[3] = e.currentCrawlingSite;
temp_arr[4] = e.sitesToCrawl;
temp_arr[5] = e.done;
temp_arr[6] = e.failedUrls;
temp_arr[7] = e.failed;
OnProgressEvent(temp_arr);
}
private void GetLists(List<string> allWebSites)
{
}
public class BackgroundWebCrawlingProgressEventHandler : EventArgs
{
public List<string> csFiles { get; set; }
public string mainUrl { get; set; }
public int levels { get; set; }
public List<string> currentCrawlingSite { get; set; }
public List<string> sitesToCrawl { get; set; }
public bool done { get; set; }
public int failedUrls { get; set; }
public bool failed { get; set; }
}
protected void OnProgressEvent(Object[] some_params)
{
if (ProgressEvent != null)
ProgressEvent(this,
new BackgroundWebCrawlingProgressEventHandler()
{
csFiles = (List<string>)some_params[0],
mainUrl = (string)some_params[1],
levels = (int)some_params[2],
currentCrawlingSite = (List<string>)some_params[3],
sitesToCrawl = (List<string>)some_params[4],
done = (bool)some_params[5],
failedUrls = (int)some_params[6],
failed = (bool)some_params[7]
});
}
private void PauseWorker()
{
if (mainBackGroundWorker.IsBusy)
{
_busy.Reset();
}
}
private void ContinueWorker()
{
_busy.Set();
}
public void CancelWorker()
{
ContinueWorker();
mainBackGroundWorker.CancelAsync();
}
}
}
这是单击以中止操作的按钮单击事件:
private void button3_Click(object sender, EventArgs e)
{
bgwc.CancelWorker();
cancel = true;
wcfg.toCancel = cancel;
}
当我点击按钮时,它会转到BackgroundWebCrawling类并执行:
public void CancelWorker()
{
ContinueWorker();
mainBackGroundWorker.CancelAsync();
}
但是由于某种原因而不是立即停止背景工作者等待/挂起它直到它将完成当前进程大约2-3-5秒然后停止。 而是立即停止进入Form1并执行此部分:
private void bgwc_ProgressEvent(object sender, BackgroundWebCrawling.BackgroundWebCrawlingProgressEventHandler e)
{
this.Invoke(new MethodInvoker(delegate { label7.Text = e.sitesToCrawl.Count.ToString(); }));
this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, "Level: " + e.levels.ToString(), Color.Green); }));
this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, " Loading The Url: ", Color.Red); }));
this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, e.mainUrl + "...", Color.Blue); }));
if (e.done == true)
{
this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, " Done " + Environment.NewLine, Color.Red); }));
doneWebPages++;
this.Invoke(new MethodInvoker(delegate { label12.Text = doneWebPages.ToString(); }));
}
if (e.failed == true)
{
this.Invoke(new MethodInvoker(delegate { label10.Text = e.failedUrls.ToString(); }));
this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, " Failed " + Environment.NewLine, Color.Green); }));
}
if (e.failedUrls > 0)
{
this.Invoke(new MethodInvoker(delegate { label10.Text = e.failedUrls.ToString(); }));
e.failed = true;
if (e.failed == true)
{
this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, " Failed " + Environment.NewLine, Color.Green); }));
e.failed = false;
}
}
this.Invoke(new MethodInvoker(delegate { label13.Text = (e.failedUrls + doneWebPages).ToString(); }));
}
之后它回到BackgroundWebCrawling类并执行此操作:
if (ProgressEvent != null)
ProgressEvent(this,
new BackgroundWebCrawlingProgressEventHandler()
{
csFiles = (List<string>)some_params[0],
mainUrl = (string)some_params[1],
levels = (int)some_params[2],
currentCrawlingSite = (List<string>)some_params[3],
sitesToCrawl = (List<string>)some_params[4],
done = (bool)some_params[5],
failedUrls = (int)some_params[6],
failed = (bool)some_params[7]
});
然后在同一个班级做这一行:
OnProgressEvent(temp_arr);
///将此类的数据+附加数据发送到Form1 ..
毕竟这是在Form1中完成的事件:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button3.Enabled = false;
checkBox1.Enabled = true;
checkBox2.Enabled = true;
numericUpDown1.Enabled = true;
button1.Enabled = true;
button2.Enabled = true;
this.Text = "Web Crawling";
if (cancel == true)
{
label6.Text = "Process Cancelled";
}
问题是当我点击按钮并等待首先完成该过程时,为什么它不会中止操作? 也许我需要以某种方式停止/中止第二个背景?
答案 0 :(得分:0)
首先,这看起来像是矫枉过正的代码,但也许有必要......
其次,你的取消实际上并没有取消任何东西,它只是设置了你必须采取行动的标志,当你回复那个标志时,你只是break
,那么你等待计数到返回0.如果您想立即停止,请不要break
,return
休息之后,你仍然在你的工作人员中做以下事情。您也可以在取消时将counter
设置为0。但是,回报更具有前瞻性。
while (counter > 0)
{
Thread.Sleep(10);
}