-2
這是我有兩個背景工作者的背景工作者。爲什麼當我點擊取消操作時,它並沒有立即停止背景工作?
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";
}
的問題是,爲什麼它不放棄經營權當我點擊按鈕和等待第一個完成該過程? 也許我需要停止/中止第二個背景嗎?
不,看來第二個(secondryBackGroundWorker)不會影響當我取消操作。當我取消時,至少它不會去secondryBackGroundWorker_DoWork事件。 –
您是否將'WorkerSupportsCancellation'設置爲'true'? –
當然,這將需要一段時間。 BGW正在執行一個調用Sleep()並且不關注CancellationPending的循環。它可能永遠不會停止,在兩個線程中更改* count *基本上不是線程安全的。 –