Утилизировать класс

В моем проекте есть класс DataParse. Я делаю несколько соединений с Ethernet. Каждый раз, когда открывается новое соединение, я создаю новый класс следующим образом. Кроме того, в этом классе есть один таймер.

public Dictionary<string, DataParse> classDictionary = new Dictionary<string, DataParse>();

Подключить код

string IpAddress = Ip.Text;
int Port = Convert.ToInt32(PortName.Text);
var IpPort = IpAddress + ":" + Port;
classDictionary.Add(IpPort, new DataParse());
classDictionary[IpPort].DataParseRun(IpPort);

Я хочу уничтожить созданный класс при закрытии соединения. Я хочу уничтожить таймер с классом.

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

Отключенный код

private void Events_Disconnected(object sender, ClientDisconnectedEventArgs e)
{
    classDictionary[e.IpPort].Dispose();
    classDictionary.Remove(e.IpPort);
}

Код DataParse

public class  DataParse : IDisposable
    {

    private bool _disposed = false;
    private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (_disposed)
        {
            return;
        }

        if (disposing)
        {
            // Dispose managed state (managed objects).
            _safeHandle?.Dispose();
        }

        _disposed = true;
    }
    
    Timer timer;
    byte[] moduleBuffer;
    int writePtr;
    string key;



    public void DataParseRun(string IpPort)
    {
        moduleBuffer = new byte[50000];
        writePtr = 0;
        timer = new Timer(new TimerCallback(ParseTimer), null, TimeSpan.FromMilliseconds(1000), TimeSpan.FromMilliseconds(200));
        key = IpPort;

    }
     
    void ParseTimer(object state)
    {
        var abc = key;    
    }

   
}

Как я могу уничтожить класс.

GC.Collect(); - для чего здесь эта строчка? Также похоже, что _safeHandle на самом деле не используется.
Dennis 17.12.2020 11:49

видел это в приложении. Добавил попробовать. Я удалил его сейчас, но он все еще не работает.

user14497385 17.12.2020 11:52

Как я могу использовать _safeHandle?

user14497385 17.12.2020 11:53

1) с _safeHandle?. вы увеличиваете цикломатическую сложность, которая должна быть на уровне 1.2) если вы планируете систематически явно вызывать очистку, делайте это с помощью release() (или любой другой) функции, а не с dispose() codinghelmet.com /articles/… 3) dispose() полезно, когда вы вызываете нативные функции, которые нужно уничтожить; для управляемого это делается автоматически.

Soleil 17.12.2020 14:55

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

user14497385 20.12.2020 00:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
136
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте вручную удалить таймер в методе Dispose. Насколько я вижу, таймер никогда не утилизируется.

timer.Dispose();

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

Он будет собран с помощью сборщика мусора, как только все ссылки на экземпляр будут потеряны или недоступны — поэтому, как только вы, как советует Трикс в своем ответе, удалите экземпляр из словаря и избавитесь от таймера и SafeHandle, ничто не должно мешать GC собирать его. Однако, когда именно это произойдет, зависит не от вас.

РЕДАКТИРОВАТЬ2: Я бы сказал так. Вы можете попробовать проверить это, прочитав какой-нибудь огромный файл в String, чтобы он занимал 100 МБ, и посмотреть, освобождается ли память после того, как вы избавитесь от всего. По-видимому, есть также прямой вызов, который вы можете сделать для GC: GC.Collect() - если вы вызываете его из класса, я не думаю, что он соберет этот класс, но для тестирования вы можете вызвать его после удаления из словаря.

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

user14497385 17.12.2020 12:11

Благодарю за ваш ответ. Я понимаю, что когда я следую упомянутым вами процессам, сборщик мусора автоматически соберет их через определенное время. Итак, timer.Dispose(); и _safeHangle? .Утилизировать(); это достаточно ?

user14497385 17.12.2020 12:28

Я создал функцию внутри класса. После выполнения процесса удаления я все еще могу получить к нему доступ, когда захочу получить доступ к этой функции. Означает ли это, что операция, которую я применил, не удалась?

user14497385 18.12.2020 07:08

Без вызова Dispose DataParse = null; Через некоторое время после вызова команды память освобождается. Я не мог понять.

user14497385 18.12.2020 07:30

Итак, если я правильно понял, у вас есть что-то вроде DataParse dp = new DataParse(); dp.Dispose(); [SomeCode]...; dp.Somefunction(). Что здесь происходит, так это то, что у вас есть ссылка на экземпляр класса, поэтому он не может быть уничтожен - вот почему я рекомендовал проверять память, потому что, пока у вас есть ссылка на экземпляр, вы не сможете его уничтожить (я думаю). Без вызова Dispose Сборка мусора в конечном итоге происходит, и она определяет, что ваш объект больше не используется из-за отсутствия каких-либо ссылок, и освобождает память.

PureVodka 18.12.2020 12:01

Большое спасибо за ваш интерес. Отмечаю как ответ. Потому что избавление от таймера решило мою проблему. Я тоже считал, что лучше проверить память прямо сейчас.

user14497385 18.12.2020 12:39

Другие вопросы по теме