我有一个非常简单的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”循环,但我有不同的情况。
感谢任何澄清回复!谢谢!
答案 0 :(得分:1)
一般信息
BackgroundWorkers用于将工作委托给后台线程,因此不会阻止UI线程。
实际工作应该在DoWork事件的事件处理程序中进行。此事件从后台工作线程调用,因此您不能直接更新任何UI元素。
当后台工作程序完成时,即当DoWork
事件处理程序返回时,会引发RunWorkerCompleted事件。它是在创建后台工作程序的线程上引发的,后者通常表示UI线程,可用于更新UI控件。
最后,当您调用ProgressChanged方法时,会引发ReportProgress事件。它也是在创建后台工作程序的同一个线程上引发的,您可以使用它来更新UI。
您的示例代码
您应该将执行实际工作的代码放在backgroundWorker_DoWork
方法中。而不是致电Console.WriteLine
向用户提供有关进度调用backgroundWorker.ReportProgress
的反馈。在backgroundWorker_ProgressChanged
方法中,您可以更新进度条。