代码之家  ›  专栏  ›  技术社区  ›  perilbrain

行为变化和空引用异常的生成

c#
  •  2
  • perilbrain  · 技术社区  · 16 年前

    我在2小时前做了这个程序,当我面对这个预先保存的.xls文件时,它运行得很好。但当我关闭它并启动新实例时,它开始生成空引用异常为什么??请解释。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    
    
    
    using System.IO;
    
    using System.Threading;
    using Microsoft.Office.Interop;
    using Excel = Microsoft.Office.Interop.Excel;
    
    
    namespace svchost
    {
    
        class MainClass
        {
            Excel.Application oExcelApp;
    
    
            static void Main(string[] args)
            {
                MainClass mc = new MainClass();
                while (true)
                {
                    if (mc.chec())
                    {
                        Console.WriteLine("RUNNING");
    
                        Thread.Sleep(4000);
                    }
                    else
                    {
                        Console.WriteLine("NOT RUNNING");
    
                        Thread.Sleep(8000);
                    }
    
                }
    
    
            }
            public bool chec()
            {
    
    
    
                try
                {
                    oExcelApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
                    Excel.Workbook xlwkbook = (Excel.Workbook)oExcelApp.ActiveWorkbook;
    
                    //****PROBLEM FROM HERE*********
    
                Console.WriteLine(xlwkbook.Name + "\n");
                ke kw = new ke(ref oExcelApp,ref xlwkbook);
    
                Console.WriteLine(xlwkbook.Author);
    
                xlwkbook = null;
            }
            catch (Exception ec)
            {
                oExcelApp = null;
                System.GC.Collect();
                Console.WriteLine(ec);
                return false;
    
            }
            oExcelApp = null;
    
            System.GC.Collect();
            return true;
        }
    }
    
    
    
    
    class ke
    
    {
        public ke(ref Excel.Application a1, ref Excel.Workbook b1)
        {
            Excel.Worksheet ws = (Excel.Worksheet)a1.ActiveSheet;
            Console.WriteLine(a1.ActiveWorkbook.Name + "\n" + ws.Name);
            Excel.Range rn;
            rn = ws.Cells.Find("657/07", Type.Missing, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
       Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, Type.Missing, Type.Missing);
            Console.WriteLine(rn.Text);
    
        }
    
    }
    
    }
    
    2 回复  |  直到 16 年前
        1
  •  5
  •   Aaronaught    16 年前

    1. 别写台词 GC.Collect()

    2. 线 oExcelApp = null 一事无成。我猜这是从一个VB脚本/应用程序“翻译”过来的,你必须在那里编写 Set xxx = Nothing ,然后发现GC是不确定的,您可以用它来“修复” GC.收集() . 让GC去做它的工作,如果你不知道你在做什么,就不要乱来。

    3. Exception 吃了它。。。不要再扔,不要包装,不要伐木,什么都没有。在这种情况下,它应该是 finally ,带有 return true try 阻止和 return false 最后 阻止。

    4. ref 方法中不需要引用语义的参数。把他们赶走。

    5. 无意义的类和方法名。我们怎么能理解这里发生了什么?

    6. 从不检查 null rn = ws.Cells.Find -此方法可以返回 . 这个 ActiveWorkbook 属性也可以返回 无效的 ,然后把这个传给 ke 构造函数,它不验证工作簿是否为有效引用。最后, Marshal.GetActiveObject 无效的 你从不检查以确保它成功。

    7. 创建一个类并使用它的构造函数来完成可以在单个方法中完成的工作。我不明白为什么 类甚至存在-它没有方法或属性!。给这个方法一个合适的名字,去掉它 类,并将其放入执行其余工作的同一个类中。

    8. 声明变量,然后在下一行分配它们。我想这更像是一个代码风格的问题,但再次让我认为这是某种从VB的自动翻译。如果在声明变量后立即赋值给变量,则将声明和赋值放在同一行上, Range rn = ... .

    9. Thread.Sleep ,大概是为了防止某种种族状况,而不是一种可靠的方法。

        2
  •  0
  •   perilbrain    16 年前
         public bool chec()
                {
                    Excel.Application oExcelApp;
    
    
                    try
                    {
    
                        oExcelApp = (Excel.
    
    Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application"); ;
                    if (oExcelApp.ActiveWorkbook != null)
                    {
                        Excel.Workbook xlwkbook = (Excel.Workbook)oExcelApp.ActiveWorkbook;
    
    
                        ke k = new ke(ref oExcelApp, ref xlwkbook);
    
                    }
    
    
                }
                catch 
                {
                    if (reg > 100) { } else { reg++; goto End; }//public static int reg=0;
                    oExcelApp = null;
    
                    /*Process[] ppo = Process.GetProcessesByName("EXCEL");
                    foreach(Process pppp in ppo)
                    {
                      pppp.Kill();
                    }*/
    
                    End:
                    return false;
    
                }
    
                   finally{ oExcelApp = null;
                    System.GC.Collect();}
    
    
    
    
                return true;
            }
        }