Richard.Berry100 Ответов: 3

Выход из приложения: me.Close vs Application.Выход против Конца


Я использую приложение windows forms. frmMain - это объект запуска приложения. В Sub New я проверяю, присутствует ли конфигурационный файл, а если нет, то хочу, чтобы форма закрылась и завершила работу приложения. Если файл конфигурации присутствует, мне нужно получить путь к базе данных из файла конфигурации и проверить, существует ли файл базы данных. Если файл базы данных не существует, приложение должно быть закрыто.
С помощью приведенного ниже кода я получаю сообщение о том, что конфигурационный файл отсутствует, но затем я все равно получаю исключение "не удается получить доступ к удаленному объекту - frmMain" после закрытия messagebox.
Я попробовал использовать приложение.Exit вместо Me.Close, но затем frmMain все еще открывается после отображения messagebox в Sub New.
Я понимаю, что End не следует использовать, так как это не избавляет от всех объектов правильно.

Как мне выйти из приложения чисто, если есть проблема либо с файлом конфигурации, либо с файлом базы данных?

Public Sub New()

       ' This call is required by the designer.
       InitializeComponent()

       ' Add any initialization after the InitializeComponent() call.
       If Not IO.File.Exists(Application.StartupPath & "\simmstock.config") Then
           MessageBox.Show("Config file is missing. The application cannot start")
           Me.Close()
       Else
           GetConfigData()
           LoadAllTables()
           Setup()
           SetupUser()
           Loading = False
       End If

   End Sub

   Private Sub GetConfigData()
       Xml = New XMLManager("Simmstock.config")
       dbPath = Xml.GetKey("DBPath")
       If IsNothing(dbPath) Then
           MessageBox.Show("Error in config file. Confirm DBPath Key. Application cannot start.")
           Me.Close()
       End If
       If Not IO.File.Exists(dbPath) Then
           MessageBox.Show("Cannot access the Database specified in the config file. The application cannot start. Ensure you have access to the network or call your System Admisistrator")
           Me.Close()
       End If
       DA = New DataAccess(dbPath, 2007)
       UserID = Xml.GetKey("User")
   End Sub

Sergey Alexandrovich Kryukov

Что такое "конец"?! End - это ключевое слово, не имеющее ничего общего с завершением приложения.
--СА

Richard.Berry100

Я не эксперт, но если я поставлю "конец" вместо Me.Close, это убьет приложение?

Если я наберу End, intellisense покажет:
оператор end
Немедленно Останавливает Выполнение

3 Ответов

Рейтинг:
28

OriginalGriff

Проблема в том, где вы делаете тест.
То, что вы делаете, - это попытка убить форму в конструкторе, что не совсем работает, потому что конструктор возвращается, а фреймворк затем пытается открыть убитую и удаленную форму.

Переместите свой код в событие Load для формы и используйте метод Close - тогда он будет работать нормально.


Рейтинг:
1

Sergey Alexandrovich Kryukov

Во-первых, пожалуйста, посмотрите мой комментарий к этому вопросу. Функционально нет такого понятия, как "конец".

Ты перепутал в своей голове несколько простых вещей. Метод Close есть на самом деле System.Windows.Forms.Form.Close Он закрывает форму, которая не имеет ничего общего с приложением. Но! — давайте посмотрим на точку входа:

Sub Main()
    '...
    Dim myMainForm As New SomeFormClass()
    'by this call, it is decided which form is main:
    Application.Run(myMainForm) 
End Sub


Основная форма отличается в одном аспекте: если она закрывается, то метод Application.Run выходы. Вот и все. Вот почему приложение в конечном итоге завершается, как вы можете видеть из приведенного выше кода.

Метод Application.Exit просто безоговорочно завершает работу приложения, выполняя некоторые предварительные действия перед выходом, такие как удаление всех форм и, следовательно, всех составленных объектов по мере необходимости.

Теперь проблема заключается в следующем: если форма не является основной, вы можете закрыть ее, но вы не можете открыть ее снова, иначе вы получите исключение, о котором вы упомянули. Таким образом, шаблон должен быть таким: если вы хотите позволить пользователю нажать кнопку закрытия, но хотите использовать эту форму снова позже... захватите попытку закрыть ее и вместо этого спрячьте. Это делается путем обработки события FormClosed или переопределение виртуального метода OnFormClosing пожалуйста , смотрите:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.onformclosing.aspx[^].

В этой статье обратите внимание на использование объекта недвижимости Cancel параметра аргументов события. Вам нужно будет назначить true ему нужно предотвратить действие по умолчанию, то есть закрытие.

—СА


Richard.Berry100

Спасибо за информацию. Я установил frmMain в качестве формы запуска в разделе свойства проекта, поэтому на самом деле я не использую Sub Main() в качестве вашего примера выше? Или, может быть, это то, что делает Visual Studio? Однако, похоже, это работает нормально, если я помещаю проверку файла в событие загрузки формы. Не уверен, есть ли разница?

Sergey Alexandrovich Kryukov

Ты ничего не понял. Вы, конечно же, используете Sub Main в своем коде; это код, написанный для вас, когда вы создаете приложение Forms из шаблона. Это ваша запись. Я просто объяснил, как приложение закрывается в другой ситуации, потому что это была ваша забота.

Пожалуйста, посмотри еще раз. Это то, что вам действительно нужно понять по этому вопросу, ваша функциональность является производной от этих фактов.
--СА

Sergey Alexandrovich Kryukov

Кроме того, вы не должны думать о своем приложении как о чем-то, что Visual Studio "делает", даже частично. Такого понятия не существует. Это помогает вам генерировать часть рутинного кода, и ничего больше. Вы можете разработать код, удалить студию и по-прежнему иметь возможность создавать приложение и запускать его, просматривать его код и т. д.

Он даже не включает компилятор и конструктор для файлов проектов и решений-все это делается компиляторами и MSBuild, которые являются частью распространяемого .NET Framework.

Весь код-ваш. Вы единственный автор и должны знать, где находится ваше "главное" и все остальное.
--СА

Richard.Berry100

Спасибо, СА. Я не понимал разницы между "приложением" и моей основной формой, а также того, что приложение открывает форму из Sub Main. Есть ли способ увидеть Sub Main в Visual Studio?

Кроме того, в моем случае то, что я на самом деле хотел сделать, - это правильно закрыть форму, которая затем вызовет приложение.Беги к выходу. (Не Приложение.Выход)
По ссылке, которую вы предложили, если форма закрыта правильно: событие FormClosing происходит, когда форма закрывается. Когда форма закрыта, она удаляется, освобождая все ресурсы, связанные с формой.
Я в значительной степени "самоучка/интернет" и явно упустил из виду многие основы, так что спасибо за ваше время, чтобы объяснить!

Sergey Alexandrovich Kryukov

В вашем проекте нет ничего, что вы не могли бы увидеть.

Я не использую VB.NET, но автоматически сгенерированный файл с методом точки входа (Main, и это может быть либо функция, либо Sub, параметры тоже необязательны), вероятно, является "program.vb". Если нет, найдите "приложение.Беги" (он должен быть только на одном месте). Вы не имеете никакого отношения к этому файлу (в типичном "обычном" приложении), мне просто нужно было объяснить, где начинается и заканчивается приложение и что определяет, какая форма является основной.

Точка входа в приложение-это одна из фундаментальных вещей, которые каждый должен знать. Вы можете доверять себе как разработчику только в том случае, если знаете, как писать целые приложения своими руками без всех этих глупых дизайнеров и шаблонов проектов. Поверьте мне, это совсем не сложно. Автоматически сгенерированный код предоставляется вам для того, чтобы уберечь вас от скучного набора текста, но не потому, что вы ничего не должны знать. Вы должны понимать каждую строку в вашем коде, иначе вся идея программирования окажется напрасной.

Что касается самоучки, кстати: вы думаете, что другие люди очень разные? Неужели вы думаете, что кто-то преподает такую мелочь, как один конкретный язык или фреймворк в колледже? Но даже если и так, в этом нет никакого смысла. Колледж должен преподавать математику, скажем, общую теорию языков и многое другое, но не конкретный язык; это просто пустая трата драгоценного времени. Я просто не знаю порядочных людей, которые не были бы самоучками. Я имею в виду, что такие вещи не могут служить оправданием.
--СА

Amir Mahfoozi

+5

Sergey Alexandrovich Kryukov

Спасибо, Амир.
--СА

MaryOB77062

"Основная форма отличается в одном аспекте: если она закрывается, то применяется метод.Запуск выходов" не соответствует действительности. В vb.net вы можете установить режим завершения работы на момент закрытия последней формы. Это свойство задается в приложении.Дизайнер.VB в подкатегории новый

MaryOB77062

"Теперь проблема заключается в следующем: если форма не является основной, вы можете закрыть ее, но вы не можете открыть ее снова" формы могут быть закрыты и показаны снова по желанию.

Рейтинг:
1

Member 13920522

End
это пропускает заключительный аргумент, поэтому он идет прямо вперед и закрывает все приложение.
Me.Close
это просто закрывает одну форму и проходит через заключительный аргумент.
Application.Exit
это закрывает все приложение, но проходит через заключительный аргумент для каждой формы.

Надеюсь, это поможет!


Richard Deeming

Спрашивали, отвечали и решали SIX AND A HALF YEARS AGO.

Stick to answering recent questions.