Обновите индикатор выполнения при обработке файла
У меня есть веселый проект, над которым я сейчас работаю. Это проект C# WinForms. По сути, предполагается, что использование загружает файл решения Visual Studio, а затем приложение анализирует его: создает объекты в соответствии с тем, что написано в файле и т. Д. (Подробное объяснение того, что он делает, на самом деле не имеет отношения к вопросу, поэтому я буду остановите здесь).
У меня есть основная форма (frmMain
), который предоставляет интерфейс для загрузки файла, а также имеет индикатор выполнения (analyzingProgressBar
), который должен показывать прогресс при разборе файла, так как это занимает несколько секунд. Я создал BackgroundWorker
, но я застрял - как я могу обновить prgressbar в соответствии с фактическим прогрессом?
Мой код:
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
toolStripPseudo.Text = String.Empty;
toolStripPseudo.Spring = true;
}
private void openSolutionToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openSolutionDialog.ShowDialog() == DialogResult.OK)
{
Solution openSolution = new Solution(openSolutionDialog.FileName);
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.RunWorkerCompleted);
worker.ProgressChanged += new ProgressChangedEventHandler(this.ProgressChanged);
worker.DoWork += new DoWorkEventHandler(this.DoWork);
// start the worker thread
worker.RunWorkerAsync(openSolution);
}
}
private void DoWork(object sender, DoWorkEventArgs e)
{
// get a reference to the worker that started this request
BackgroundWorker workerSender = sender as BackgroundWorker;
Solution openSolution = e.Argument as Solution;
openSolution.AnalyzeSolution();
workerSender.ReportProgress() //What do I do here?
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// TODO add graphics
}
public void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
analyzingProgressBar.Value = e.ProgressPercentage;
}
}
1 ответ
Обычно, чтобы показать, как меняется прогресс, вам нужно иметь какой-то цикл в вашем DoWork
событие, а затем процент и / или сообщение обратно в поток пользовательского интерфейса:
private void DoWork(object sender, DoWorkEventArgs e)
{
var workerSender = (BackgroundWorker)sender;
// I know I'm making this up.. I have no idea what your method does/returns
var filesToAnalyze = ((Solution)e.Argument).AnalyzeSolution();
for (var i = 0; i < filesToAnalyze.Length; i++)
workerSender.ReportProgress(0, "Analyzing file #" + i);
}
Поскольку у вас нет ничего для перебора, но вы просто хотите вызвать свой единственный метод в отдельном фоновом потоке, не беспокойтесь о том, как сообщить о прогрессе. Если вы не прервете этот единственный вызов метода, вы ничего не сможете сделать.
Добавить ProgressBar
с Style
установить на "Marquee"; покажите это перед началом потока и спрячьте в RunWorkerCompleted
событие:
progressBar.Show();
worker.RunWorkerAsync(openSolution);
...
private void DoWork(object sender, DoWorkEventArgs e)
{
var openSolution = (Solution)e.Argument;
// Run long method (which can't touch the UI, or it'll throw an exception)
openSolution.AnalyzeSolution();
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar.Hide(); // Hide progress bar when job complete
}
AnalyzeSolution () просто вызывает некоторые (скажем, 5) другие методы подряд. Могу ли я сделать что-то вроде добавления 20% на индикатор выполнения после завершения каждого из методов?
Да, но тогда вам придется вызывать эти 5 методов, а не просто вызывать AnalyzeSolution()
:
private void DoWork(object sender, DoWorkEventArgs e)
{
var workerSender = (BackgroundWorker)sender;
var openSolution = (Solution)e.Argument;
openSolution.RunMethodOne();
workerSender.ReportProgress(20);
openSolution.RunMethodTwo();
workerSender.ReportProgress(40);
...
}