后台工作人员完成事件在实际完成工作之前触发
Background Worker Completed Event is firing before it is actually finished doing work
在我的应用程序中,当用户单击菜单项时,系统会提示他们 select 一个文件,然后我使用后台工作程序加载和解析,在此期间将进度报告给进度条手术。工作完成后,我开始一个新的 window 并将解析后的数据传递给它。出于某种原因,新的 window 在数据被解析并传递空参数而不是数据之前被打开。
我的点击事件:
private void CIRCUIT_INSTALATION_SCHEDULED_Click(object sender, RoutedEventArgs e)
{
//prevents users from selecting other menu items
disableAll();
System.Windows.Forms.OpenFileDialog mainExcelFileDialog = new System.Windows.Forms.OpenFileDialog();
mainExcelFileDialog.InitialDirectory = System.Configuration.ConfigurationManager.AppSettings["MainWorkbookDirectory"];
mainExcelFileDialog.Title = "Main Excel File";
mainExcelFileDialog.ShowDialog();
string mainPath = mainExcelFileDialog.FileName;
this.Cursor = System.Windows.Input.Cursors.Wait;
BackgroundWorker cisWorker = new BackgroundWorker();
cisWorker.DoWork += cisWorker_DoWork;
cisWorker.ProgressChanged+=cisWorker_ProgressChanged;
cisWorker.RunWorkerCompleted += cisWorker_RunWorkerCompleted;
cisWorker.RunWorkerAsync(mainPath);
}
我的工作:
void cisWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
using (FileStream fs = new FileStream(e.Argument.ToString() , FileMode.Open))
{
//copy filestream to memorystream chunk by chunk, reporting progress.
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[32768];
int read;
int steps = Convert.ToInt32(fs.Length / buffer.Length);
int i = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
i++;
var progress = new Decimal(i) / new Decimal(steps);
var outOf = Math.Round(progress * 50);
worker.ReportProgress(Convert.ToInt32(outOf));
}
worker.ReportProgress(50);
ms.Position = 0;
//load excel workbook dataset from memorystream
using (var xlr = Excel.ExcelReaderFactory.CreateOpenXmlReader(ms))
{
xlr.IsFirstRowAsColumnNames = true;
mainWorkbook = xlr.AsDataSet();
worker.ReportProgress(100);
}
}
}
}
我的完成:
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow();
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
编辑:
我将 mainPath 参数添加到 cisWorker.runWorkerAsync() 方法。不幸的是,问题仍然存在。
Henk Holterman 是对的。我收到一个错误,因为我没有设置 cisWorker.WorkerReportsProgress = true;
我仍然不知道为什么错误没有破坏调试器,因为它没有被处理,但是我在我的 Completed 方法中做了一个打印语句,这有助于我追查罪魁祸首。
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine(e.Error);
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow(mainWorkbook, abfsDatabase);
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
基本上你应该检查你的数据是否为空,即在 DoWork 期间没有发生错误
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
/* Your mainWorkbook shouldn't be null */
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow();
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
else
{
// Handle error
}
}
在我的应用程序中,当用户单击菜单项时,系统会提示他们 select 一个文件,然后我使用后台工作程序加载和解析,在此期间将进度报告给进度条手术。工作完成后,我开始一个新的 window 并将解析后的数据传递给它。出于某种原因,新的 window 在数据被解析并传递空参数而不是数据之前被打开。
我的点击事件:
private void CIRCUIT_INSTALATION_SCHEDULED_Click(object sender, RoutedEventArgs e)
{
//prevents users from selecting other menu items
disableAll();
System.Windows.Forms.OpenFileDialog mainExcelFileDialog = new System.Windows.Forms.OpenFileDialog();
mainExcelFileDialog.InitialDirectory = System.Configuration.ConfigurationManager.AppSettings["MainWorkbookDirectory"];
mainExcelFileDialog.Title = "Main Excel File";
mainExcelFileDialog.ShowDialog();
string mainPath = mainExcelFileDialog.FileName;
this.Cursor = System.Windows.Input.Cursors.Wait;
BackgroundWorker cisWorker = new BackgroundWorker();
cisWorker.DoWork += cisWorker_DoWork;
cisWorker.ProgressChanged+=cisWorker_ProgressChanged;
cisWorker.RunWorkerCompleted += cisWorker_RunWorkerCompleted;
cisWorker.RunWorkerAsync(mainPath);
}
我的工作:
void cisWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
using (FileStream fs = new FileStream(e.Argument.ToString() , FileMode.Open))
{
//copy filestream to memorystream chunk by chunk, reporting progress.
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[32768];
int read;
int steps = Convert.ToInt32(fs.Length / buffer.Length);
int i = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
i++;
var progress = new Decimal(i) / new Decimal(steps);
var outOf = Math.Round(progress * 50);
worker.ReportProgress(Convert.ToInt32(outOf));
}
worker.ReportProgress(50);
ms.Position = 0;
//load excel workbook dataset from memorystream
using (var xlr = Excel.ExcelReaderFactory.CreateOpenXmlReader(ms))
{
xlr.IsFirstRowAsColumnNames = true;
mainWorkbook = xlr.AsDataSet();
worker.ReportProgress(100);
}
}
}
}
我的完成:
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow();
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
编辑: 我将 mainPath 参数添加到 cisWorker.runWorkerAsync() 方法。不幸的是,问题仍然存在。
Henk Holterman 是对的。我收到一个错误,因为我没有设置 cisWorker.WorkerReportsProgress = true;
我仍然不知道为什么错误没有破坏调试器,因为它没有被处理,但是我在我的 Completed 方法中做了一个打印语句,这有助于我追查罪魁祸首。
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine(e.Error);
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow(mainWorkbook, abfsDatabase);
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
基本上你应该检查你的数据是否为空,即在 DoWork 期间没有发生错误
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
/* Your mainWorkbook shouldn't be null */
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow();
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
else
{
// Handle error
}
}