System.ObjectDisposedException Message: Safe handle has been closed

Topics: Logging Application Block
Aug 29, 2007 at 5:13 PM
After deploying the latest EntLib (3.1), we're getting the following error on a regular basis:

Exception Type: System.ObjectDisposedException Message: Safe handle has been closed
ObjectName: Data: System.Collections.ListDictionaryInternal
TargetSite: Boolean ReportEvent(System.Runtime.InteropServices.SafeHandle, Int16, UInt16, UInt32, Byte[], Int16, Int32, System.Runtime.InteropServices.HandleRef, Byte[])
HelpLink: NULL
Source: System
StackTrace Information Details: ====================================== at Microsoft.Win32.UnsafeNativeMethods.ReportEvent(SafeHandle hEventLog, Int16 type, UInt16 category, UInt32 eventID, Byte[] userSID, Int16 numStrings, Int32 dataLen, HandleRef strings, Byte[] rawData) at System.Diagnostics.EventLog.InternalWriteEvent(UInt32 eventID, UInt16 category, EventLogEntryType type, String[] strings, Byte[] rawData, String currentMachineName) at System.Diagnostics.EventLog.WriteEvent(EventInstance instance, Byte[] data, Object[] values) at System.Diagnostics.EventLog.WriteEvent(EventInstance instance, Object[] values) at System.Diagnostics.EventLogTraceListener.TraceData(TraceEventCache eventCache, String source, TraceEventType severity, Int32 id, Object data) at Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedTraceListenerWrapperBase.TraceData(TraceEventCache eventCache, String source, TraceEventType severity, Int32 id, Object data) at Microsoft.Practices.EnterpriseLibrary.Logging.LogSource.TraceData(TraceEventType eventType, Int32 id, LogEntry logEntry, TraceListenerFilter traceListenerFilter) at Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter.ProcessLog(LogEntry log)

Has anyone else experienced this? Any thoughts?
Aug 29, 2007 at 11:55 PM
Are you doing anything unusual with threading, such as sharing a single LogWriter instance across threads?
Aug 30, 2007 at 4:54 PM
i just checked the code and it looks like we're calling Logger.Writer.Dispose() after we write each entry. i'm guessing that's the root of the problem.
Aug 31, 2007 at 4:50 AM


maird wrote:
i just checked the code and it looks like we're calling Logger.Writer.Dispose() after we write each entry. i'm guessing that's the root of the problem.


That would do it alright. You shouldn't dispose a LogWriter unless you never want to use it again. In normal circumstances you'll just use a single LogWriter (via Logger) for the lifetime of the project and never dispose it at all.

Tom
Aug 27 at 10:49 AM
Edited Aug 27 at 1:17 PM
Hi tom,
I have to delete the log file that logger is using after all the info has been logged and move it to Archive.I have found two solutions
 1.Logger.Reset()
 2.Logger.write.Dispose().
if not using above two methods I'm able to delete the log file only if the service which is writing to log is restarted or stopped .
Can you suggest me the which one i should use but I'm aware that both has demerits in their own way.Could you please provide any better solution.
Editor
Aug 27 at 3:01 PM
Under the covers Logger.Reset() does a dispose with some additional checks such as synchronizing access to the LogWriter and ensuring that the LogWriter is not null. If the application is multi-threaded (e.g. web application) then you will need to ensure that Logger.Write() does not fail while archiving the file. To do this you would need to synchronize all logging activity.

You could also consider using the RollingFlatFileTraceListener which will do a simple archive of the log file based on size or time. Another approach would be a custom trace listener that does exactly what you need (calls to a file-based trace listener are already synchronized so you don't have to manage that yourself).

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to