我在2小时前完成了这个程序,当我面对这个预先存档的.xls文件时,它运行得很好.但当我关闭并启动新实例时,它开始生成null refrence异常为什么?? plz解释.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
哇,那里发生了很多可怕的事情.
GC.Collect()除非你有充分的理由,否则不要写行.这不是其中之一.
这条线oExcelApp = null没有任何成就.我猜这是从你必须编写的VB脚本/应用程序中"翻译"的Set xxx = Nothing,然后发现GC是不确定的并且你可以"修复"它GC.Collect().让GC完成它的工作,如果你不知道你在做什么,不要搞砸它.
抓住顶层Exception并吃它......不是重新投掷,不是包装,不是记录,没有.在这种情况下,它应该是一个finally,return true在try块内部和块return false之后finally.
ref由于任何原因不需要引用语义的方法中的参数.摆脱它们.
无意义的类和方法名称.我们怎么理解这里发生了什么?
从不检查null结果,这无疑是您获得例外的原因.我看到几个例子.第一个是在行开头之后rn = ws.Cells.Find- 此方法可以返回null.该ActiveWorkbook属性也可以返回null,并将其传递给ke构造函数,该构造函数不验证工作簿是否为有效引用.最后,Marshal.GetActiveObject也可以返回null,你永远不会检查,以确保它成功.
创建一个类并使用其构造函数执行可在单个方法中完成的相同工作.我不明白为什么ke班级甚至存在 - 它没有方法或属性!为方法指定一个正确的名称,删除ke该类并将其放在正在执行其余工作的同一个类中.
声明变量,然后在下一行分配它们.我想这更像是代码风格的问题,但我再次认为这是VB的某种自动翻译.如果在声明变量后立即分配变量,则将声明和赋值放在同一行上,Range rn = ....
使用Thread.Sleep,可能是为了防止某种竞争条件 - 而不是一种可靠的手段.
希望其中一件事(可能是#6)将引导您找到解决方案......
| 归档时间: |
|
| 查看次数: |
783 次 |
| 最近记录: |