将控制台转换为Winforms。如何用backgroundworker实现两个进度条?

时间:2013-06-08 15:41:46

标签: c# multithreading winforms progress-bar backgroundworker

我有一个非常简单的WinForms应用程序,它使用从某些Web服务收集国家和地区的类,并将收集的数据存储到文件中。此CollectData类在控制台应用程序中运行良好,并通过Console.WriteLine

通知每个步骤

我的代码如下:

    public class CollectData
    {
        public string OutputFile { get; private set; }

        public CollectData(string outputFile)
        {
            OutputFile = outputFile;
        }

    public void ProceedCollectingData()
    {
        Console.WriteLine("Getting countries...");

        List<string> countries = GetWorldCountries();
        foreach (string country in countries)
        {
            Console.WriteLine("Getting regions of country: " + country);

            List<string> regions = GetCountryRegions(country);
            AppendToFile(OutputFile, country, regions);
        }
    }

        private List<string> GetWorldCountries()
        {
            List<string> list = new List<string>();
            System.Threading.Thread.Sleep(20000); // here service fills list of countries.
            return list;
        }

        private List<string> GetCountryRegions(string country)
        {
            List<string> list = new List<string>();
            System.Threading.Thread.Sleep(20000); // here service fills list of regions.
            return list;
        }

        private void AppendToFile(string outputFile, string country, List<string> regions)
        {
            // Save everything into output file.
        }
    }

和WinForm代码:         private void btnCollectData_Click(object sender,EventArgs e)         {             CollectData collectData = new CollectData(tbOutputFile.Text.Trim());             collectData.ProceedCollectingData();

        //???? what should be here
        backgroundWorker.RunWorkerAsync(collectData);
    }

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        //???? what should be here?
    }

    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        //???? what should be here?
    }

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        progressBarCountries.Value = 100;
        progressBarRegions.Value = 100;

        lblCurrentlyProgressingStatus.Text = "Done";
    }

出了什么问题,我应该在课堂上改变什么,我应该打开什么,从课堂方法返回或重新开发,开发内部课程逻辑和通知progressBars的正确方法是什么?

我通过互联网进行了搜索,所有示例都像使用Thread.Sleep的backgroundWorker_DoWork中的简单“for”循环,但我有不同的情况。

感谢任何澄清回复!谢谢!

1 个答案:

答案 0 :(得分:1)

一般信息

BackgroundWorkers用于将工作委托给后台线程,因此不会阻止UI线程。

实际工作应该在DoWork事件的事件处理程序中进行。此事件从后台工作线程调用,因此您不能直接更新任何UI元素。

当后台工作程序完成时,即当DoWork事件处理程序返回时,会引发RunWorkerCompleted事件。它是在创建后台工作程序的线程上引发的,后者通常表示UI线程,可用于更新UI控件。

最后,当您调用ProgressChanged方法时,会引发ReportProgress事件。它也是在创建后台工作程序的同一个线程上引发的,您可以使用它来更新UI。

您的示例代码

您应该将执行实际工作的代码放在backgroundWorker_DoWork方法中。而不是致电Console.WriteLine向用户提供有关进度调用backgroundWorker.ReportProgress的反馈。在backgroundWorker_ProgressChanged方法中,您可以更新进度条。