我正在尝试在WPF中使用2个后台工作程序但是“微调器”似乎锁定了UI线程,这阻止了进度条的移动。在我的“加载数据”功能中,它似乎偶尔会导致我的并行for循环崩溃。如果我不启动微调器的背景工作者,一切似乎都能正常工作。
我的微调背景工作者有什么问题?
(这是我第一次和背景工作者一起玩)
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;
}
这些是我的openData函数
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;
}
这些是我的微调功能
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;
}
}
}
感谢您提供任何指导
答案 0 :(得分:1)
您可以对BackgroundWorker的DoWork使用内联调用,请尝试:
void spinner_DoWork(object o, DoWorkEventArgs args)
{
this.Dispatcher.BeginInvoke(new Action(() => {
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;
}
}
}));
}