如何在我的类上使用/创建后台工作者已完成事件

本文关键字:创建 后台 工作者 事件 已完成 我的 | 更新日期: 2023-09-27 18:30:41

首先,我创建了这个类:

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;
        BackgroundWorker mainBackGroundWorker;
        BackgroundWorker secondryBackGroundWorker;
        WebcrawlerConfiguration webcrawlerCFG;
        List<WebCrawler> webcrawlers;
        int maxlevels;
        public event EventHandler<BackgroundWebCrawlingProgressEventHandler> ProgressEvent;
        // mainBack to make doWork event 
        // function that called start that get list<string> websitestocrawl anbd get int number how many threads to work at once ! in Form1 to make start to be public
        // to make progress event to the main background ! mainBack first time to make it to work without progress maybe !
        // to make getList function to get all lists from the webcrawlers instances !
        // in the mainBack to check and create instances for secondryBackground each time.
        // to the seocndry to make DoWork as it is now !
        // in the secondry to call the webcrawler from the class WebCrawler .
        // since WebCrawler is a class in the main background DoWork event before calling for a new thread for the secondry to make a new instance to the webCrawler class !!!
        // to call to the FUNCTION webCrawler to use the e.Argument to get create instance of the webCrawler function.
        // to make the progress event in the end to report for labels and richtextboxes in Form1. maybe in Form1 to use invokes for this event.
        // the function start will get parameters she need and that webcrawer need from webcrawler cfg class. this list to send to each webcrawler instance.
        public BackgroundWebCrawling()
        {
            webcrawlers = new List<WebCrawler>();
            mainBackGroundWorker = new BackgroundWorker();
            mainBackGroundWorker.DoWork += mainBackGroundWorker_DoWork;
        }
        private void mainBackGroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < WebSitesToCrawl.Count; i++)
            {
                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]
                    });
        }
    }
}

在表格1中,我有:

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";
            }
            else
            {
                label6.Text = "Process Completed";
            }
            button6.Enabled = true;
            button4.Enabled = false;
            button5.Enabled = false;
            listBox1.Enabled = true;
        }

但是我在 Form1 中没有任何 backgroundworker1,并且此已完成的事件与上述其他类中的任何后台工作者都没有以任何方式连接。

当后台工作者完成时,我如何使用/使其完成的事件将起作用?

这是 Form1 中启动后台工作程序的按钮单击事件:

private void button1_Click(object sender, EventArgs e)
        {
            WebcrawlerConfiguration wcfg = new WebcrawlerConfiguration();
            BackgroundWebCrawling bgwc = new BackgroundWebCrawling();
            wcfg.downloadcontent = downLoadImages;
            wcfg.failedUrls = failedUrls;
            wcfg.localy = LocalyKeyWords;
            wcfg.removeext = removeExt;
            wcfg.toCancel = cancel;
            bgwc.Start(sites, 3, (int)numericUpDown1.Value, wcfg);
            offlineOnline = false;
            init();
            bgwc.ProgressEvent += new EventHandler<BackgroundWebCrawling.BackgroundWebCrawlingProgressEventHandler>(bgwc_ProgressEvent);
        }

如何在我的类上使用/创建后台工作者已完成事件

目前尚不清楚要将哪个后台工作者连接到事件,但您所要做的就是:

worker.RunWorkerCompleted+= 
        new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

编辑:
因此,如果您希望在mainBackGroundWorker完成后触发此功能,它应该是:

mainBackGroundWorker.RunWorkerCompleted+= 
    new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

如果您希望在secondryBackGroundWorker完成后触发它,它应该是:

secondryBackGroundWorker.RunWorkerCompleted+= 
    new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

旁注

使用后台工作线程时,使用@Keith模板总是很方便

BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };
bw.DoWork += (sender, e) => 
   {
       //what happens here must not touch the form
       //as it's in a different thread
   };
bw.ProgressChanged += ( sender, e ) =>
   {
       //update progress bars here
   };
bw.RunWorkerCompleted += (sender, e) => 
   {
       //now you're back in the UI thread you can update the form
       //remember to dispose of bw now
   };
worker.RunWorkerAsync();