В моем проекте есть класс 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;
}
}
Как я могу уничтожить класс.
видел это в приложении. Добавил попробовать. Я удалил его сейчас, но он все еще не работает.
Как я могу использовать _safeHandle?
1) с _safeHandle?. вы увеличиваете цикломатическую сложность, которая должна быть на уровне 1.2) если вы планируете систематически явно вызывать очистку, делайте это с помощью release() (или любой другой) функции, а не с dispose() codinghelmet.com /articles/… 3) dispose() полезно, когда вы вызываете нативные функции, которые нужно уничтожить; для управляемого это делается автоматически.
Для меня это была продвинутая тема. Насколько я понимаю, когда класс не используется, он автоматически стирается из памяти.





Попробуйте вручную удалить таймер в методе Dispose. Насколько я вижу, таймер никогда не утилизируется.
timer.Dispose();
Обновлено: пока не могу комментировать, поэтому я отредактирую ответ. Насколько мне известно, вы не можете вручную просто удалить свой экземпляр из памяти.
Он будет собран с помощью сборщика мусора, как только все ссылки на экземпляр будут потеряны или недоступны — поэтому, как только вы, как советует Трикс в своем ответе, удалите экземпляр из словаря и избавитесь от таймера и SafeHandle, ничто не должно мешать GC собирать его. Однако, когда именно это произойдет, зависит не от вас.
РЕДАКТИРОВАТЬ2: Я бы сказал так. Вы можете попробовать проверить это, прочитав какой-нибудь огромный файл в String, чтобы он занимал 100 МБ, и посмотреть, освобождается ли память после того, как вы избавитесь от всего. По-видимому, есть также прямой вызов, который вы можете сделать для GC: GC.Collect() - если вы вызываете его из класса, я не думаю, что он соберет этот класс, но для тестирования вы можете вызвать его после удаления из словаря.
Да, сброс таймера вручную сработал. Но это просто похоже на избавление от таймера. Как я могу убедиться, что я отбрасываю класс, который я создал?
Благодарю за ваш ответ. Я понимаю, что когда я следую упомянутым вами процессам, сборщик мусора автоматически соберет их через определенное время. Итак, timer.Dispose(); и _safeHangle? .Утилизировать(); это достаточно ?
Я создал функцию внутри класса. После выполнения процесса удаления я все еще могу получить к нему доступ, когда захочу получить доступ к этой функции. Означает ли это, что операция, которую я применил, не удалась?
Без вызова Dispose DataParse = null; Через некоторое время после вызова команды память освобождается. Я не мог понять.
Итак, если я правильно понял, у вас есть что-то вроде DataParse dp = new DataParse(); dp.Dispose(); [SomeCode]...; dp.Somefunction(). Что здесь происходит, так это то, что у вас есть ссылка на экземпляр класса, поэтому он не может быть уничтожен - вот почему я рекомендовал проверять память, потому что, пока у вас есть ссылка на экземпляр, вы не сможете его уничтожить (я думаю). Без вызова Dispose Сборка мусора в конечном итоге происходит, и она определяет, что ваш объект больше не используется из-за отсутствия каких-либо ссылок, и освобождает память.
Большое спасибо за ваш интерес. Отмечаю как ответ. Потому что избавление от таймера решило мою проблему. Я тоже считал, что лучше проверить память прямо сейчас.
GC.Collect();- для чего здесь эта строчка? Также похоже, что_safeHandleна самом деле не используется.