Изменение в поведении и генерация исключений нулевой ссылки - PullRequest
2 голосов
/ 10 марта 2010

Я сделал эту программу 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);

    }

}

}

Ответы [ 2 ]

5 голосов
/ 10 марта 2010

Ух, там происходит много страшных вещей.

  1. Никогда не пишите строку GC.Collect(), если у вас нет очень веских причин. Это не один из тех времен.

  2. Строка oExcelApp = null ничего не выполняет. Я предполагаю, что это было «переведено» из сценария / приложения VB, где вам нужно было написать Set xxx = Nothing, а затем пришло открытие, что GC является недетерминированным и что вы можете «исправить» это с помощью GC.Collect(). Пусть GC сделает свою работу, не связывайтесь с ней, если не знаете, что делаете.

  3. Поймать верхний уровень Exception и съесть его ... не перебрасывать, не оборачивать, не регистрировать, ничего. В этом случае это, вероятно, должен быть finally, с return true внутри блока try и return false после блока finally.

  4. ref параметров в методе, который по какой-либо причине не требует ссылочной семантики. Избавься от них.

  5. Бессмысленные имена классов и методов. Как мы должны понимать, что здесь происходит?

  6. Никогда не проверяйте результаты null, и это, несомненно, то, почему вы получаете исключение. Я вижу несколько случаев. Первый - после строки, начинающейся с rn = ws.Cells.Find - этот метод может вернуть null. Свойство ActiveWorkbook также может возвращать null, и вы передаете его конструктору ke, который не проверяет, является ли рабочая книга допустимой ссылкой. Наконец, Marshal.GetActiveObject также может возвращать null, и вы никогда не проверяете его на предмет успеха.

  7. Создание класса и использование его конструктора для выполнения той же работы, что и в одном методе. Я не понимаю, почему класс ke даже существует - у него нет методов или свойств !. Дайте методу правильное имя, удалите этот класс ke и поместите его в тот же класс, который выполняет остальную часть работы.

  8. Объявление переменных и их присвоение на следующей строке. Я предполагаю, что это больше проблема стиля кода, но опять же заставляет меня думать, что это был своего рода автоматический перевод из VB. Если вы присваиваете переменные сразу же после их объявления, поместите объявление и присваивание в одну строку, Range rn = ....

  9. Использование Thread.Sleep, предположительно для предотвращения какого-либо состояния гонки - и не является надежным средством для этого.

Надеюсь, одна из этих вещей (вероятно, № 6) приведет вас к решению ...

0 голосов
/ 31 марта 2010
     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;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...