给出以下代码取消后台工作程序的最佳方法,以便Excel正确关闭。例如,如果用户在Excel工艺中间关闭表单。以下代码工作正常。只是盯着使用背景工作者,所以只是得到它的悬念,并希望以正确的方式做到这一点。基本上,下面的代码将允许用户使用复选框选择要导出的列(字段)。 int [] cols是他们选择的列的相应数字。
*这是更新的代码。我在循环期间使用了取消和中断的建议以及基本的bgw msdn文章。我想不出另一种检查何时退出Excel的方法,所以我使用了行计数。谢谢你的提示。
private void XLWorker_DoWork(object sender, DoWorkEventArgs e)
{
this.XLWorker.ReportProgress(-1);
xl._Application app = new Microsoft.Office.Interop.Excel.Application();
xl._Workbook workbook = app.Workbooks.Add(Type.Missing);
// creating new Excelsheet in workbook
xl._Worksheet worksheet = null;
// get the reference of first sheet. By default its name is Sheet1.
// store its reference to worksheet
worksheet = workbook.Sheets[1];
worksheet = workbook.ActiveSheet;
// changing the name of active sheet
worksheet.Name = "User Details";
worksheet.Cells.Font.Size = "12";
int headerCounter = 1;
foreach (int col in _export)
{
worksheet.Cells[1, headerCounter] = _form.DataGridResultsSet.Columns[col].HeaderText;
headerCounter++;
}
//Format zip code
xl.Range rngResult = null;
xl.Range FindRange = null;
int rowCount = worksheet.UsedRange.Rows.Count;
for (int columnIndex = 1; columnIndex <= worksheet.UsedRange.Rows.Count; columnIndex++)
{
FindRange = worksheet.UsedRange.Columns[columnIndex];
rngResult = FindRange.Find("ZipCode", Type.Missing, Type.Missing, Type.Missing, Type.Missing, xl.XlSearchDirection.xlNext, Type.Missing, Type.Missing, Type.Missing);
if (rngResult != null)
{
rngResult.EntireColumn.NumberFormat = "00000";
}
}
//Add rows
int colCounter = 0;
int pending = 0;
for (int i = 0; i < _form.DataGridResultsSet.Rows.Count - 1; i++)
{
if ((XLWorker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
foreach (int col in _export)
{
worksheet.Cells[i + 2, colCounter + 1] = _form.DataGridResultsSet.Rows[i].Cells[col].Value.ToString();
colCounter++;
}
colCounter = colCounter - _export.Length;
XLWorker.ReportProgress((i * 100) / _form.DataGridResultsSet.Rows.Count - 1);
}
pending = i;
}
int cancel = pending + 2;
if (cancel < _form.DataGridResultsSet.Rows.Count)
{
Marshal.FinalReleaseComObject(rngResult);
Marshal.FinalReleaseComObject(FindRange);
Marshal.FinalReleaseComObject(worksheet);
rngResult = null;
FindRange = null;
worksheet = null;
workbook.Close(false, Type.Missing, Type.Missing);
app.Application.Quit();
app.Quit();
Marshal.FinalReleaseComObject(workbook);
workbook = null;
Marshal.FinalReleaseComObject(app);
app = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
else
{
//Format sheet
worksheet.Columns.AutoFit();
worksheet.Cells.HorizontalAlignment = xl.XlHAlign.xlHAlignLeft;
worksheet.Cells.Font.Size = "11";
xl.Range rngB = (xl.Range)worksheet.Rows[1];
rngB.Font.Bold = true;
//Worker completed
XLWorker.ReportProgress(100);
Marshal.FinalReleaseComObject(rngResult);
Marshal.FinalReleaseComObject(FindRange);
Marshal.FinalReleaseComObject(rngB);
Marshal.FinalReleaseComObject(worksheet);
Marshal.FinalReleaseComObject(workbook);
rngResult = null;
FindRange = null;
rngB = null;
worksheet = null;
workbook = null;
//Sleep unti export is complete
Thread.Sleep(1000);
//Show Excel
app.Visible = true;
//Cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
private void XLWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage < 0)
{
this.buttonActExport.Text = "Calculating...";
toolStripProgressBar1.Visible = true;
toolStripStatusLabel1.Visible = true;
}
else if (e.ProgressPercentage != 100)
{
this.buttonActExport.Text = ("Exporting: " + e.ProgressPercentage.ToString() + "%");
toolStripProgressBar1.Value = e.ProgressPercentage;
}
else
{
this.buttonActExport.Text = "Done";
toolStripProgressBar1.Value = e.ProgressPercentage;
}
}
private void XLWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
this.buttonActExport.Text = "Canceled!";
}
else if (!(e.Error == null))
{
this.buttonActExport.Text = ("Error: " + e.Error.Message);
}
else
{
this.buttonActExport.Text = "Done!";
}
this.buttonActExport.Text = "Export";
this.buttonActExport.Enabled = true;
toolStripProgressBar1.Visible = false;
toolStripStatusLabel1.Visible = false;
toolStripProgressBar1.Value = 0;
}
答案 0 :(得分:1)
您需要执行“合作取消”,您需要修改您的代码以便与取消流程“合作”并优雅地停止它尝试执行的操作。您需要检查整个代码中的workerXL.CancellationPending
,如果它返回true,则执行相应的步骤以“取消”操作,例如处理必要的资源并关闭excel实例。