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(){};布洛克,一切又顺利了。非常感谢。