Я пишу программу, которая взаимодействует с Excel. У меня небольшая проблема с закрытием моего приложения, когда excel был убит через диспетчер задач.
Когда моя программа запускается, она устанавливает Excel.Application ObjApp = new Excel.Application();
Когда он закрывается, он заканчивает это
if (ObjApp != null)
{
ObjApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
ObjApp.Quit();
Environment.Exit(0);
Однако, если Excel будет отключен через диспетчер задач, и я выйду, я получаю это
«Исключение NullReferenceException не было обработано кодом пользователя» в
ObjApp.Quit();
По сути, мне нужно выяснить, как сказать
«Если ObjApp (мой экземпляр Excel) все еще доступен, закройте его, иначе не делайте этого». Как я могу это решить?
2 ответа
Вам не следует беспокоиться о том, что вы не можете контролировать. Если пользователь решит закрыть приложение Excel , которое ваша программа использует или нет, вам не следует пытаться выяснить (нет безопасного способа определить, так ли это, вы можете всегда заканчиваются состоянием гонки, но давайте не отвлекаться).
Тогда что тебе делать? Внедрите код, который позаботится о любом разумном сценарии сбоя, который может обработать ваше приложение. Что именно является причиной сбоя, не имеет значения, это может быть что угодно: это может быть пользователь, закрывающий приложение, но также может быть какая-то неясная ошибка Excel , приводящая к сбою приложения, ОС икота, аппаратный сбой, что у вас.
А как ты это делаешь? Хорошо, используйте обработку исключений:
try
{
//Normal code path goes here. Assume appObj is running;
ObjApp.Quit();
}
//optional catch clauses here
finally
{
//Safe clean up you want running in normal execution or any managable
//scenario. By safe I mean you shouldn't be handling/saving/modifying
//any sensitive data, you should just clean up your COM objects.
//Anything potentially unsafe should be handled in specific catch
//clauses where you know the nature of the exception and you can take
//specific measures to recover or shut down safely.
//In some unrecoverable scenarios this might not even run.
Marshal.FinalReleaseComObject(ObjApp);
}
Вы можете добавить предложения catch
для определенных типов исключений для входа в систему или для информирования пользователя о том, что произошло что-то непредвиденное; COMException
приходит на ум как хороший выбор, любое другое исключение, вероятно, следует передать вверх по стеку вызовов и позволить кому-то другому, кто лучше знает, обработать его.
Первый
GC.WaitForPendingFinalizers()
запустит деструкторы для objects
.
Для вашего примера, когда ObjApp == null
, тогда GC может разрушить объект ObjApp
. и тогда ObjApp
будет нулевым.
ObjApp.Quit()
необходимо позвонить до GC.WaitForPendingFinalizers()
Второй . Вы устанавливаете для ObjApp
значение null
, а после этого вызываете ObjApp.Quit()
. Если метод Quit()
нестатический, тогда программа throw NullReferenceException
ожидается.
Попробуй это:
ObjApp.Quit();
if (ObjApp != null)
{
ObjApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
Environment.Exit(0);
Лично, когда я закрываю файл Excel, я делаю следующее:
...//
this.workbook.Close();
this.application.Workbooks.Close();
this.application.Quit();
}
finally
{
Marshal.FinalReleaseComObject(this.autoFitRange);
GC.Collect();
Marshal.ReleaseComObject(this.numberFormatRange);
GC.Collect();
Marshal.ReleaseComObject(this.range);
GC.Collect();
Marshal.ReleaseComObject(this.workbook);
GC.Collect();
Marshal.ReleaseComObject(this.sheet);
GC.Collect();
Marshal.ReleaseComObject(this.workbooks);
GC.Collect();
Marshal.ReleaseComObject(this.application);
GC.Collect();
Как видите, я запускаю ReleaseComObject
для всех объектов, создаваемых при использовании COM
библиотеки Excel. Если я это сделаю, я закрою Excel, и процесс исчезнет из диспетчера задач.
Пусть это вам поможет.
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.