W mojej aplikacji trzymam sobie listę pewnych obiektów
public List<ExternalFileStorage> ExternalStorages { get; private set; }
mniejsza o to czym są te obiekty, ważne że wiążą one swoje metody z zewnętrznymi zdarzeniami (eventami). W tym przypadku uruchamia mi się funkcja Connection_BytesReceived
jeśli ze źródła danych przyjdzie jakaś wiadomość.
public ExternalFileStorage(IExternalNode connection, ILogger logger)
{
_logger = logger;
DataSource = connection;
DataSource.BytesReceived += Connection_BytesReceived;
}
ExternalStorage w pewnym momencie działania aplikacji zostaje "zresetowany". To znaczy usuwana jest obecna instancja z listy i generowana jest nowa
private void Node_ConnectionReset(object sender, ConnectionResetEventArgs e)
{
ExternalStorage relatedStorage = ExternalStorages.FirstOrDefault(x => x.DeviceId == e.RelatedNode.Id);
if (relatedStorage != null)
{
// tutaj usuwam obecny "external storage"
ExternalStorages.Remove(relatedStorage);
// tutaj tworzę nowy, powiązany z tym samym źródłem danych
CreateStorageForNode(e.RelatedNode);
}
else
{
_logger.LogError("ConnectionReset: couldn't refresh storage as it doesn't exist");
}
}
Zauważyłem, że kod w Connection_BytesReceived
(tego w ExternalStorage, który wywołuje się po nadejściu wiadomości ze źródła danych) wywołuje się wielokrotnie, im więcej resetów tym więcej razy jest wykonywany. Moja teoria jest taka, że usuwany z listy ExternalStorage nadal znajduje się w pamięci. Normalnie byłby usunięty ale garbage collector go nie tyka, bo ExternalStorage nadal jest powiązany eventami z innymi obiektami. Gdy więc przychodzi wiadomość ze źródła, wywoływany jest Connection_BytesReceived
nawet w tych obiektach, które rzekomo zostały już usunięte.
Problem polega na tym, że nie widzę w c# jawnego sposobu wywołania destruktora. Moje pytanie brzmi: czy jest jakiś sposób żeby definitywnie pozbyć się obiektu z pamięci żeby uniknąć takich sytuacji?