C# 变量有一个值,但抛出一个未设置为对象实例的对象引用
我有一个函数,可以循环C# 变量有一个值,但抛出一个未设置为对象实例的对象引用,c#,datatable,backgroundworker,void,spreadsheetlight,C#,Datatable,Backgroundworker,Void,Spreadsheetlight,我有一个函数,可以循环数据表,并使用电子表格将其保存为Excel文件,用于C 注意,循环通过数据表并保存其Excel文件输出需要时间,这取决于数据网格有多少单元格、行和列,或者从哪里提取数据表 在我的函数中使用BackgroundWorker之前,函数会正确执行。当然,没有BackgroundWorker的唯一附带说明是,当代码执行时,UI会冻结。通过使用BackgroundWorker我知道我可以通过在另一个线程上处理save函数来消除这种情况 但是在我的函数中应用了BackgroundWor
数据表
,并使用电子表格
将其保存为Excel文件
,用于C
注意,循环通过数据表
并保存其Excel文件
输出需要时间,这取决于数据网格
有多少单元格、行和列,或者从哪里提取数据表
在我的函数中使用BackgroundWorker
之前,函数会正确执行。当然,没有BackgroundWorker
的唯一附带说明是,当代码执行时,UI会冻结。通过使用BackgroundWorker
我知道我可以通过在另一个线程上处理save函数来消除这种情况
但是在我的函数中应用了BackgroundWorker
之后,整个save函数就中断了。它向我抛出一个未设置为对象实例的对象引用
,但我进行了调试和跟踪,并确保传递的两个变量中都有值,并且不为null。我使用的循环与以前相同,我甚至尝试使用For循环
下面是我遇到的一个片段。如您所见,下面的窗口显示单元格
和值
变量都包含内容。但却给我一个空引用
此外,这是我函数的完整代码
public void exportSingleDataGridToExcelFile(DataTable dt) {
using(var sfd = new SaveFileDialog()) {
sfd.FileName = string.Format("WIP Monitoring-{0}", DateTime.Now.ToString("MM.dd.yyyy"));
sfd.Filter = "Excel File (*.xlsx)|*.xlsx";
if(sfd.ShowDialog() == DialogResult.OK) {
clb.Enabled = false;
cb.Enabled = false;
btn.Visible = false;
pb.Visible = true;
pb.Value = 50;
using(var excel = new SLDocument()) {
var style = excel.CreateStyle();
style.SetHorizontalAlignment(DocumentFormat.OpenXml.Spreadsheet.HorizontalAlignmentValues.Center);
style.SetVerticalAlignment(DocumentFormat.OpenXml.Spreadsheet.VerticalAlignmentValues.Center);
var bgw = new BackgroundWorker();
bgw.WorkerReportsProgress = true;
bgw.DoWork += (ss, ee) => {
var worker = ss as BackgroundWorker;
var count = (dt.Rows.Count + 1) * dt.Columns.Count;
var steps = (double) count / 100;
var prog = 0.0;
var row = 0;
var col = 0;
//Get Column Headers
foreach(DataColumn dc in dt.Columns) {
var cell = string.Format("{0}1", col.getExCol());
var value = dc.ColumnName;
excel.SetCellValue(cell, value);
excel.AutoFitColumn(string.Format("{0}1", col.getExCol()));
excel.SetCellStyle(string.Format("{0}1", col.getExCol()), style);
prog += steps;
worker.ReportProgress(((int) prog * 100));
col++;
}
col = 0;
//Get Cell Data
foreach(DataRow dr in dt.Rows) {
foreach(DataColumn dc in dt.Columns) {
var cell = string.Format("{0}{1}", col.getExCol(), row);
var value = dr[dc].ToString();
excel.SetCellValue(cell, value);
excel.AutoFitColumn(cell, row);
excel.SetCellStyle(cell, style);
prog += steps;
worker.ReportProgress(((int) prog * 100));
col++;
}
col = 0;
row++;
}
};
bgw.ProgressChanged += (ss, ee) => {
pb.Value = ee.ProgressPercentage / 100;
};
bgw.RunWorkerCompleted += (ss, ee) => {
try {
excel.SaveAs(sfd.FileName);
form.Close();
} catch(Exception ex) {
MessageBox.Show(ex.Message, "Error while saving", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
bgw.RunWorkerAsync();
}
}
}
}
最初,在我实现我的BackgroundWorker
之前,同样的代码也可以工作
希望我能在这里了解一下。在执行后台工作程序时,
excel
中的SLDocuemnt
实例中很可能存在null
您正在使用语句在中创建excel
。这意味着在using
块的末尾,将处理excel
。但在该块中,您启动了一个后台工作程序,它使用这个excel
变量
使用
块时,后台工作程序的运行时间肯定比长,因此当您尝试访问它并执行引发异常的行时,excel
已被释放
直接的解决办法是不要在这里使用using
。但是,最好在后台工作者的方法中实例化excel
变量,因为在外部似乎并不需要它。我非常确定,在读取异常时,您的excel
变量是空的。而不是方法调用中的值
我怀疑这是由于您所做的背景工作。using
语句中的excel
变量没有传递到bgw.DoWork
事件处理非常好的问题显示顺便说一句;布置得很好,有很多信息。@Claies似乎就是这样。谢谢你注意到这一点me@Zil嗯,我需要尽可能好地描述我的问题,以便其他人能够理解我的问题是什么。他也怀疑同样的事情。在发布这个问题之后,我尝试删除using块,并在函数顶部声明excel
变量。问题解决了,我又让它工作了。我想我会把这个问题留在这里,以防其他人和我有同样的想法。thanksi删除了using(){};布洛克,一切又顺利了。非常感谢。