IDisposable в Синглтоне - Хорошая практика? - PullRequest
3 голосов
/ 19 февраля 2010

У меня есть класс Singleton, который управляет подключением к внешнему устройству. Идея моего приложения заключается в том, что мне нужно, чтобы это внешнее устройство было представлено все время, пока приложение живо.

Singleton имеет следующие функциональные возможности:

  1. Инициализация, ищите устройство во время запуска приложения
  2. обменивайтесь данными с внешним устройством, обратите внимание, что оно может распространяться на несколько сборок в нескольких точках.
  3. Закрыть соединение при выходе из приложения.

В последней части я думаю о том, чтобы поместить код в метод Dispose класса singleton, чтобы гарантировать, что ресурс всегда очищается при закрытии. Но поскольку я использую Singleton, а срок службы синглтона будет завершен только при выходе из приложения, нет необходимости явно закрывать соединение в Dispose, так как соединение все равно будет закрыто.

Итак, вопрос в том, должен ли я поместить код закрытого соединения в метод Dispose?

Ответы [ 5 ]

3 голосов
/ 19 февраля 2010

Внедрение IDisposable само по себе не означает, что Dispose будет вызываться при выходе.

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

Даже в этом случае вам не гарантируется, что код выполняется, поэтому, возможно, мне неясно, что вы пытаетесь выполнить или какую проблему вы пытаетесь решить.

Править:

В соответствии с комментариями OP, лучший вариант (для его желания, чтобы код "cleanup" выполнялся без специального вызова и проверки) был бы поместить его в деконструктор / финализатор.Обратите внимание, что запуск не гарантирован, но в большинстве случаев должен выполняться без вызова (в отличие от Dispose):

public class Foo
{
    public Foo()
    {
        //Constructor
    }

    ~Foo()
    {
        // Deconstructor/finalizer
    }
}
2 голосов
/ 19 февраля 2010

IDisposable! = Деструктор, как C ++, он должен вызываться явно.

В любом случае наличие одноразового синглтона не имеет особого смысла, ИМО. Что, если какой-то код на самом деле избавился от вашего синглтона? Что произойдет, если какой-то другой код попытается получить доступ к этому синглтону сейчас? По этой причине вам, вероятно, не следует закрывать соединение там.

На самом деле, вы должны , а не даже иметь идентификатор Singleton, который можно разместить на месте .

Лучшим вариантом может быть привязка Singleton к одному из событий выхода .NET. Возможно, используйте событие Application.ApplicationExit (или Application.Exit) или что-то подобное.

1 голос
/ 19 февраля 2010

Это плохой дизайн. Вам бы лучше иметь методы Open и Close, которые вы вызываете в соответствующее время. Это будет проще для тестирования, отладки и поддержки.

0 голосов
/ 19 февраля 2010

Как уже говорили другие, Dispose не будет вызываться автоматически при выходе, однако будет вызван метод финализатора. Я бы сделал это вместо того, чтобы выполнить логику очистки при выходе из приложения.

0 голосов
/ 19 февраля 2010

Делайте и то, и другое, как у, есть явный метод Close () или Shutdown (), а также вызывайте его в dispose (отслеживать, если он вызывается и т. Д., См. Справку по шаблону dispose ...)

Таким образом, вы можете реализовать интерфейс IDisposable (который делает намерение очевидным) и вызвать его в своем коде.

Используете ли вы блок "finally" вокруг кода запуска?

internal static class App
{
    [STAThread]
    private static void Main(string[] args)
    {
        try
        {
            Thing.Startup();
            Application.Run();
        }
        finally
        {
            Thing.Shutdown(); // or dispose
        }
    }
}

Получи мой дрейф ?!

PK: -)

PS: «Синглтон» должен быть записан как обычный класс, синглтонная часть должна быть предметом внешнего использования

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