Aargh, garbage collection.... 
Ik ben bezig met het maken van een errorlogger. (Zie dit topic).
Ik heb dus een class Logger, die er als volgt uit ziet:
WriteLog is dus een static method die ik in een applicatie als volgt kan
aanroepen:
Dit werkt perfect. Adhv de gespecifieerde argumenten gaat PrepareLogger maatregelen
treffen om de juiste LogWriter te gaan klaarzetten. Dan wordt de WriteLog method
aangeroepen van de betreffende LogWriter en wordt de error weggeschreven. Tot daar geen
probleem.
Echter, bij het afsluiten van de applicatie die de Logger.WriteLog method aanroept, wil
ik een aantal resources vrijgeven. Bv, het sluiten van de databank connectie of het
sluiten van de textfile naar waar errors weggeschreven worden.
Ik had gedacht om dit in de destructor te doen van de LogWriter classes:
Nu stuit ik soms op het volgende probleem:
Ik heb een aantal errors gelogged in m'n applicatie en ik sluit de applicatie af.
De destructors van _TextLogger en _DbLogger worden aangeroepen en de EndLogging()
method wordt uitgevoerd.
Zoals je kunt zien wil ik dat die EndLogging() method nog een entry wegschrijft, zodat
ik kan weten wanneer het loggen gestopt werd.
Bij het wegschrijven van die informatie krijg ik echter soms volgende fouten:
reeds gesloten. En dat terwijl de Close() method van die file toch enkel maar aangeroepen
wordt in EndLogging nadat ik die stop-informatie weggeschreven heb.
In andere gevallen krijg ik dan een dergelijke fout, maar dan bij de DatabaseLogWriter:
hoe ik nu m'n resources goed kan vrijgeven.
Ik heb al zitten denken om die 'stop-info' niet weg te schrijven. Ik zou dan gewoon in de
destructor van de DatabaseLogWriter de connectie sluiten en in de destructor van de FileLogWriter
de file sluiten. Dit heb ik reeds geprobeerd, en dat lukt blijkbaar probleemloos. Ik krijg dan nl. geen fouten bij het aanroepen van _Conn.Close en _LogFile.Close().
* whoami vind dat hij nogal redelijk veel topics opent de laatste tijd.
* whoami vind ook dat dit nogal een lap tekst is.
Ik ben bezig met het maken van een errorlogger. (Zie dit topic).
Ik heb dus een class Logger, die er als volgt uit ziet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| class Logger { private static Logger _logger; private TextFileLogWriter _TextLogger; private DatabaseLogWriter _DbLogger; private LogWriter _LogWriter; public Logger() { _TextLogger = new TextFileLogWriter(); _DbLogger = new DatabaseLogWriter(); } static Logger() { _logger = new Logger(); } public static void WriteLog (...) { _logger.PrepareLogger(); _logger._LogWriter.WriteLog(...); } } |
WriteLog is dus een static method die ik in een applicatie als volgt kan
aanroepen:
code:
1
| Logger.WriteLog(...); |
Dit werkt perfect. Adhv de gespecifieerde argumenten gaat PrepareLogger maatregelen
treffen om de juiste LogWriter te gaan klaarzetten. Dan wordt de WriteLog method
aangeroepen van de betreffende LogWriter en wordt de error weggeschreven. Tot daar geen
probleem.
Echter, bij het afsluiten van de applicatie die de Logger.WriteLog method aanroept, wil
ik een aantal resources vrijgeven. Bv, het sluiten van de databank connectie of het
sluiten van de textfile naar waar errors weggeschreven worden.
Ik had gedacht om dit in de destructor te doen van de LogWriter classes:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| internal class DatabaseLogWriter { ~DatabaseLogWriter() { this.EndLogging(); } public override void EndLogging() { this.WriteLog("Logging ended"); this._Conn.Close(); base.EndLogging(); } } |
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| internal class TextFileLogWriter() { ~TextFileLogWriter() { this.EndLogging(); } public override void EndLogging() { this.WriteLog("Logging ended"); this._LogFile.Close(); base.EndLogging(); } } |
Nu stuit ik soms op het volgende probleem:
Ik heb een aantal errors gelogged in m'n applicatie en ik sluit de applicatie af.
De destructors van _TextLogger en _DbLogger worden aangeroepen en de EndLogging()
method wordt uitgevoerd.
Zoals je kunt zien wil ik dat die EndLogging() method nog een entry wegschrijft, zodat
ik kan weten wanneer het loggen gestopt werd.
Bij het wegschrijven van die informatie krijg ik echter soms volgende fouten:
Bij het wegschrijven van de stop-informatie naar de TextFileLogger is m'n file blijkbaarAn unhandled exception of type 'System.ObjectDisposedException' occurred in mscorlib.dll
Additional information: Cannot write to a closed TextWriter.
reeds gesloten. En dat terwijl de Close() method van die file toch enkel maar aangeroepen
wordt in EndLogging nadat ik die stop-informatie weggeschreven heb.
In andere gevallen krijg ik dan een dergelijke fout, maar dan bij de DatabaseLogWriter:
Nu denk ik dat die garbage collector er voor iets tussen zit, en ik zou dus graag willen wetenAn unhandled exception of type 'System.InvalidOperationException' occurred in system.data.dll
Additional information: Handle is not initialized.
hoe ik nu m'n resources goed kan vrijgeven.
Ik heb al zitten denken om die 'stop-info' niet weg te schrijven. Ik zou dan gewoon in de
destructor van de DatabaseLogWriter de connectie sluiten en in de destructor van de FileLogWriter
de file sluiten. Dit heb ik reeds geprobeerd, en dat lukt blijkbaar probleemloos. Ik krijg dan nl. geen fouten bij het aanroepen van _Conn.Close en _LogFile.Close().
* whoami vind dat hij nogal redelijk veel topics opent de laatste tijd.
* whoami vind ook dat dit nogal een lap tekst is.
https://fgheysels.github.io/