变量具有值但抛出未设置为对象实例的对象引用

时间:2016-06-16 07:55:56

标签: c# datatable backgroundworker void spreadsheetlight

我有一个循环DataTable的函数,并使用Excel File SpreadSheetLight将其保存为C#

注意循环DataTable并保存其Excel File输出需要时间,具体取决于DataGrid所拥有的单元格数,行数和列数,或DataTable所在的位置摘自。

在我的函数中使用BackgroundWorker之前,该函数正确执行。没有BackgroundWorker的唯一旁注当然是UI在代码执行时冻结。并且通过利用BackgroundWorker我知道我可以通过在另一个线程上处理保存功能来消除这种情况。

但在我的函数中应用BackgroundWorker后,整个保存功能都会中断。它抛出了Object Reference not set to an instance of an Object,但我调试并跟踪并确保传递的两个变量都包含值,并且不为null。我使用的循环与之前相同,我甚至尝试使用For Loop

这是我遇到的一个片段。如您所见,下面的窗口显示cellvalue变量都包含内容。然后抛出我的空参考。

enter image description here

此外,这是我的功能的完整代码

        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之前就已经有效了。

希望我能在这里接受一些步行。

2 个答案:

答案 0 :(得分:2)

当您的后台工作程序执行时,SLDocuemnt中的excel实例内的某些内容很可能是null

您正在excel声明中创建using。这意味着在using块结束时,excel将被处置。但是在该块中,您启动了一个使用此excel变量的后台工作程序。

后台工作程序肯定比using阻止运行的时间更长,因此当您尝试访问它并执行引发异常的行时,excel已经被释放。

立即解决方案将不在此处使用using。但也许最好在背景工作者的方法中实例化excel变量 ,因为看起来你无论如何都不需要它。

答案 1 :(得分:1)

我非常确定您的excel变量在读取异常时是Null的变量。不是方法调用中的值。

我怀疑这是由于你的背景工作所致。