2013-09-10 57 views
0

在Form1中,我刪除/刪除了_busy變量。在Form1頂部我所做的:爲什麼背景工作者在點擊按鈕時不會暫停?

BackgroundWebCrawling bgwc; 
在將Button4暫停單擊事件我做

然後:

private void button4_Click(object sender, EventArgs e) 
{ 
    bgwc.PauseWorker(); 
    label6.Text = "Process Paused"; 
    button5.Enabled = true; 
    button4.Enabled = false; 
} 

在button5點擊事件按鈕我所做的:

private void button5_Click(object sender, EventArgs e) 
{ 
    bgwc.ContinueWorker(); 
    label6.Text = "Process Resumed"; 
    button4.Enabled = true; 
    button5.Enabled = false; 
} 

和取消按鈕點擊事件:

private void button3_Click(object sender, EventArgs e) 
{ 
    bgwc.CancelWorker(); 
    cancel = true; 
} 

然後我檢查Form1中完成的事件,如果取消是真的還是假的:

if (cancel == true) 
{ 
    label6.Text = "Process Cancelled"; 
} 
else 
{ 
    label6.Text = "Process Completed"; 
} 

這是怎麼BackgroundWebCrawling類看起來像現在:

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

     private void secondryBackGroundWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      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--; 
     } 

     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) 
     { 
      // OK .. so now you get the data here in e 
      // and here you should call the event to form1 
      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); /// Send the data + additional data from this class to Form1.. 
             /// 
      /* 
      * temp_arr[0] = csFiles; 
       temp_arr[1] = mainUrl; 
       temp_arr[2] = levels; 
       temp_arr[3] = currentCrawlingSite; 
       temp_arr[4] = sitesToCrawl;*/ 
     } 

     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) // Probably you need to some vars here to... 
     { 
      // some_params to put in evenetArgs.. 
      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] 
        }); 
     } 

     public void PauseWorker() 
     { 
      if (mainBackGroundWorker.IsBusy) 
      { 
       _busy.Reset(); 
      } 
     } 

     public void ContinueWorker() 
     { 
      _busy.Set(); 
     } 

     public void CancelWorker() 
     { 
      ContinueWorker(); 
      mainBackGroundWorker.CancelAsync(); 
     } 

    } 
} 

所以我添加的方法的停頓繼續取消。在dowork活動中,我改變了所有的東西並添加了一些東西。

但是,當我點擊按鈕沒有任何效果。不暫停,不繼續,不取消。沒有。

+0

而'ManualResetEventHandle'如何與'BackgroundWorker'相關。要取消工作人員,您必須使用其內置功能。用_busy.WaitOne()來代碼代碼# –

回答

3

您從不檢查mainBackGroundWorker_DoWork方法中的_busy狀態;

for (int i = 0; i < WebSitesToCrawl.Count; i++) 
{ 
    _busy.WaitOne(); 
    //... 
} 

你也應該有你的ManualResetEvent _busy類與BackgroundWorker的

ManualResetEvent _busy = new ManualResetEvent(true); 
public BackgroundWorker mainBackGroundWorker; 

public void PauseWorker() 
{ 
    if(mainBackGroundWorker.IsBusy) 
    { 
     _busy.Reset(); 
    } 
} 

public void ContinueWorker() 
{ 
    _busy.Set(); 
} 

Form1

private void button4_Click(object sender, EventArgs e) 
{ 
    bgwc.PauseWorker(); 
    //... 
} 

private void button5_Click(object sender, EventArgs e) 
{ 
    bgwc.ContinueWorker(); 
    //... 
} 

取消BackgroundWorker的,你可以使用CancellationPending財產和CancelAsync方法。注意:你應該先取消暫停工人。

public void CancelWorker() 
{ 
    ContinueWorker(); 
    mainBackGroundWorker.CancelAsync(); 
} 

private void mainBackGroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker worker = sender as BackgroundWorker; 
    for (int i = 0; i < WebSitesToCrawl.Count; i++) 
    { 
     _busy.WaitOne(); 
     if ((worker.CancellationPending == true)) 
     { 
      e.Cancel = true; 
      break; 
     } 
     //... 
    } 
} 

如果不幫你,然後你有mainBackGroundWorker代碼和secondryBackGroundWorker問題。

  1. 此代碼僅暫停mainBackGroundWorker,但不會暫停secondBackGroundWorkers。與取消一樣。如果主要工作人員被取消?它會等待所有的中等工作者完成工作。另外,如果你暫停主工人?你仍然可以從中學工作者那裏得到新的結果。

  2. 你不處理錯誤。如果您在第二個工作人員中有例外情況,那麼您不會收到任何關於此事的通知,並且您的主要工作人員也不會停止,因爲counter永遠不會是0

  3. 有可能是另一個問題,女巫造成這種行爲。

+0

該操作取消了嗎? – user2760148

+0

@ user2760148不,_busy.WaitOne()等待線程被取消暫停。我用取消代碼更新了答案。 –

+0

德米特里什麼都沒有。它不工作。我會用當前的代碼更新我的問題,我是如何做到的。 – user2760148

相關問題