c # Различие в поведении, когда вызов метода не комментируется по сравнению с раскомментированием всего в вызываемом методе - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть приложение, которое использует расширение Selenium Browser для Chrome.

Поскольку это расширение не закрывает браузер Chrome при выходе из процесса, я добавил в свое приложение следующий код:

static void OnProcessExit(object sender, EventArgs e)
{
    API.Quit();
}
class API
{
    public static IWebDriver browser = new ChromeDriver(Service(), Options());
    public static void Quit()
    {
        if (!String.IsNullOrEmpty(browser.CurrentWindowHandle))
        {
            browser.Quit();
            browser.Dispose();
        }
    }
}

Обратите внимание, что оба значения, OnProcessExit и Quit, находятся в двух отдельных классах, файлах и пространствах имен. Я собрал их здесь для облегчения просмотра кода.

Кажется, есть ошибка, которая открывает Chrome, когда драйвер еще не открыт. Вот почему я реализовал случай if.

Теперь прибывает странная вещь: Даже когда я раскомментирую все внутри Quit(), откроется браузер:

static void OnProcessExit(object sender, EventArgs e)
{
    API.Quit();
}
class API
{
    public static IWebDriver browser = new ChromeDriver(Service(), Options());
    public static void Quit()
    {
    /*
        if (!String.IsNullOrEmpty(browser.CurrentWindowHandle))
        {
            browser.Quit();
            browser.Dispose();
        }
    */
    }
}

Принимая во внимание, что когда я раскомментирую вызов, браузер не открывается:

static void OnProcessExit(object sender, EventArgs e)
{
    //API.Quit();
}
class API
{
    public static IWebDriver browser = new ChromeDriver(Service(), Options());
    public static void Quit()
    {
        if (!String.IsNullOrEmpty(browser.CurrentWindowHandle))
        {
            browser.Quit();
            browser.Dispose();
        }
    }
}

Мой вопрос: почему мое приложение ведет себя по-разному, когда я раскомментирую вызов или все в Quit()?

1 Ответ

0 голосов
/ 12 ноября 2018

Я думаю, это потому, что статический конструктор. В вашем первом примере ваш псевдокод выглядит так:

  1. Звоните API.browser = new ChromeDriver(Service(), Options());
  2. Звоните API.Quit()

Во втором примере ничего не происходит, потому что вы не вызываете статический класс.

Для дальнейшего тестирования попробуйте создать этот метод внутри класса API:

public static void FakeInit() //use to invoke static class constructor.
{
    //leave it empty.
}

А затем вызвать его вместо Quit:

API.FakeInit();

И вы увидите, что браузер инициализирован, но не закрыт. Это кажется волшебным, но этот вызов на самом деле делает это:

  1. Звоните API.browser = new ChromeDriver(Service(), Options());
  2. Звоните API.FakeInit(), который пуст

PS

Основная рекомендация - не используйте static, если вы не работаете с расширениями или маршалируете какой-то неуправляемый код. Просто используйте это так:

new API().Quit();

Это совершенно нормально, вы можете создать его при запуске, передать его в другие классы, закрыть и утилизировать, когда захотите. И таким образом вы будете в полной мере осведомлены о том, что происходит, и почему ваш браузер открывается в каком-то непредсказуемом месте только потому, что вы вызвали какой-то вспомогательный метод из статического класса. Хотя я часто использую static для методов расширения (для создания DSL), мне очень не нравится его использование в качестве синглтона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...