I've created a loading form within my C# WinForms application that is shown during long processes. I've added a progress bar to my loading form that I would like to update to give some feedback of loading to the user.
Within my loading form code, I have created a new BackgroundWorker and added DoWork and ProgressChanged event handlers. The problem is that the backgroundWorker_ProgressChanged is not being called. I have inserted break points into the function and they are not caught.
Where am I going wrong? Any help appreciated. Thanks.
frmLoading:
public frmLoading()
{
InitializeComponent();
//check if bg worker is null
if (backgroundWorker == null)
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
}
backgroundWorker.WorkerReportsProgress = true;
//start
backgroundWorker.RunWorkerAsync();
}
backgroundWorker_DoWork:
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100);
backgroundWorker.ReportProgress(i);
}
}
backgroundWorker_ProgressChanged:
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//update value of progress bar
progressBar1.Value = e.ProgressPercentage;
//set the text of the progress bar
this.Text = e.ProgressPercentage.ToString();
}
Here's how you would do this with Progress<int>
and Task.Run
:
public frmLoading()
{
InitializeComponent();
IProgress<int> progress = new Progress<int>(p =>
{
//update value of progress bar
progressBar1.Value = p;
//set the text of the progress bar
this.Text = p.ToString();
});
Task.Run(async () =>
{
for (int i = 1; i <= 100; i++)
{
await Task.Delay(TimeSpan.FromSeconds(0.1));
progress.Report(i);
}
});
}
Personally I prefer Microsoft's Reactive Framework:
public frmLoading()
{
InitializeComponent();
Observable
.Interval(TimeSpan.FromSeconds(0.1))
.Take(100)
.ObserveOn(this)
.Select(p => p + 1)
.Subscribe(p =>
{
//update value of progress bar
progressBar1.Value = p;
//set the text of the progress bar
this.Text = p.ToString();
});
}