I am trying to use 2 background workers in WPF however the "spinner" seems to lock the UI thread which stops the progress bar from moving along. It also seems to cause occasional crashes with my parrallel for loops in the "load data" function I have. If I don't kick off the spinner's background worker, everything seems to work fine.
What is wrong with my spinner background worker?
(this is my first time playing with background workers)
BackgroundWorker _spinthatspinner = new BackgroundWorker();
BackgroundWorker _openDataWorker;
string data_fileName;
private void Load_Data_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog OFD = new Microsoft.Win32.OpenFileDialog();
if (OFD.ShowDialog() == true)
{
data_fileName = OFD.FileName;
//set initial state
this.myDataGrid.IsEnabled = false;
this.spinner.Visibility = System.Windows.Visibility.Visible;
dataLoadProg.Minimum = 0;
dataLoadProg.Maximum = 100;
dataLoadProg.Visibility = System.Windows.Visibility.Visible;
//kick off opening the data loader
_openDataWorker = new BackgroundWorker();
_openDataWorker.DoWork += _openDataWorker_DoWork;
_openDataWorker.ProgressChanged += _openDataWorker_ProgressChanged;
_openDataWorker.RunWorkerCompleted += _openDataWorker_RunWorkerCompleted;
_openDataWorker.WorkerReportsProgress = true;
_openDataWorker.RunWorkerAsync();
//kick off the spinner
_spinthatspinner = new BackgroundWorker();
_spinthatspinner.DoWork += spinner_DoWork;
_spinthatspinner.ProgressChanged += spinnner_prog;
_spinthatspinner.RunWorkerCompleted += spinnerSpint_completed;
_spinthatspinner.WorkerReportsProgress = true;
_spinthatspinner.RunWorkerAsync(); //if I comment out this, loading bar works fine, no crashes
}
return;
}
These are my openData Functions
void _openDataWorker_DoWork(object sender, DoWorkEventArgs e)
{
System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.AboveNormal; //tried without and with
m_currentData = new myData();
openData(data_fileName, m_currentData);
}
void openData(string filename, myData data)
{
//this function is complex but it
//it basically boils down to this
//...code omitted..
while ((line = file.ReadLine()) != null)
{
stringData.AddLine(line);
percentageF += progressPercentageForEachLine;
m_openMaldiWorker.ReportProgress((int)percentageF);
}
//at this point the progress bar is filled and ideally the spinner would start (but kicking it off here seems to cause more problems)
data.Load(stringData); //in here I have some parallel for loops to process the data collected
}
//move progress bar along
void _openDataWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
dataLoadProg.Value = e.ProgressPercentage;
}
//enable and fill UI controlls
void _openDataWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
analysisDataContext.FillWithData(m_currentData); //ok fill the data grid
this.myDataGrid.IsEnabled = true;
}
These are my spinner functions
void spinnerSpint_completed(object o, RunWorkerCompletedEventArgs args)
{
this.spinner.Visibility = System.Windows.Visibility.Hidden;
}
void spinnner_prog(object sender, ProgressChangedEventArgs e)
{
_spinnerRotation.Angle = e.ProgressPercentage;
}
void spinner_DoWork(object o, DoWorkEventArgs args)
{
System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.Idle; //tried without and with
float angle = 0;
bool stopSpinning = m_currentData != null && m_currentData.isLoaded == true;
while (!stopSpinning )
{
//spin something
angle++;
if (angle > 360.0f)
{
angle = 0.0f;
}
_spinthatspinner.ReportProgress((int)angle);
if (m_currentData != null && m_currentData.isLoaded == true)
{
stopSpinning = true;
}
}
}
Thank you for any guidance