I have a program that takes 10-20 seconds to start. I need to show a window with a progress bar when the program starts up. I know BackgroundWorker\'s are the correct way to do
It really is very easy to use backgroundworker.
public partial class Window1 : Window
{
BackgroundWorker worker = new BackgroundWorker();
public Window1()
{
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ReportsProgress = true;
worker.ProgressChanged += new ProgressChangedEventHandler(update_progress);
}
void worker_DoWork(object sender, DoWorkEventArgs e){
DoSomeLongTask();
//call worker.ReportProgress to update bar
}
void update_progress(object sender, ProgressChangedEventArgs e)
{
myscrollbar.Value = e.Value;
}
}
The keything to keep in mind is to never touch gui stuff from DoWork method. That has to through ProgressChanged/ReportProgress
If you don't want the background worker you need to adjust your code, to do the long task in the new thread.
using System;
using System.Threading;
using System.Windows;
namespace WpfApplication1
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Thread t = new Thread(DoSomeLongTask);
t.Start();
// switch this with the DoSomeLongTask, so the long task is
// on the new thread and the UI thread is free.
ShowLoadingWindow();
}
}
}
If you want to then update a progress bar from your "DoSomeLongTask" method then you'll need to ensure that you call invoke. For example:
delegate void ProgressDelegate(int Progress);
private void UpdateProgress( int Progress)
{
if (!progressBar1.Dispatcher.CheckAccess())
{
progressBar1.Value = Progress;
}
else
{
ProgressDelegate progressD = new ProgressDelegate(UpdateProgress);
progressBar1.Dispatcher.Invoke(progressD, new object[] { Progress });
}
}
You're still doing the long task in the main thread. You need to show the loading window in the main thread and do the long task in the background.
Using a BackgroundWorker is really the simplest solution for this:
BackgroundWorker bw; LoadingWindow lw; public Window1() { bw = new BackgroundWorker(); lw = new LoadingWindow(); bw.DoWork += (sender, args) => { // do your lengthy stuff here -- this will happen in a separate thread ... } bw.RunWorkerCompleted += (sender, args) => { if (args.Error != null) // if an exception occurred during DoWork, MessageBox.Show(args.Error.ToString()); // do your error handling here // close your loading window here ... } // open and show your loading window here ... bw.RunWorkerAsync(); // starts the background worker }