I've wrote a windows service that performs simple functions within our application. To ensure safe running of the service - if it errors we want to know where when how - it logs to a text file - in this instance BLAH.log.
The code is executed within a timer which runs at 30 second intervals and polls folders. Each part of the process will log to the log file.
The service will throw an IOException exception. See below for this and my code sample (in a nutshell).
If I strip the code out and put in in a stand alone EXE it works fine. No exceptions are thrown.
Am I missing something in my code or has anyone else had issues in this kind of scenario?
Do we need to use the GC.KeepAlive call to ensure timer does not get destroyed (see below) ?
Andez
System.IO.IOException: The process cannot access the file '\\DEVMACH\Sandbox\BLAH.log' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamWriter.CreateFile(String path, Boolean append)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(String path, Boolean append)
at TEST.CommonLibrary.MYAPP.ApplicationFileLogger.Wri teLine(String text, Boolean logDate)
at TEST.MYAPP.Services.ProcessingService.MyProcessing Service.DoProcessing()
' This is the in the service onstart event
_logFile = New ApplicationFileLogger("\\DEVMACH\Sandbox\BLAH.log" )
m_timer = New System.Timers.Timer(5000)
AddHandler m_timer.Elapsed, AddressOf Timer_Tick
m_timer.Enabled = True
m_timer.Start()
GC.KeepAlive(m_timer)
WriteToTraceFile("The service has started.", .LogMaximum)
' end
' 1 wrapper to log to the text file - this is a seperate DLL
Private Sub WriteToTraceFile(ByVal text As String)
_logFile.WriteLine(text, True)
End Sub
Private Sub Timer_Tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
Try
m_timer.Enabled = False
DoSomething()
Catch ex As Exception
WriteToTraceFile("The application has hit an exception")
Finally
m_timer.Enabled = True
End Try
End Sub
Private Sub DoSomething()
WriteToTraceFile("DoSomething")
DoSomemore()
End Sub
Private Sub DoSomemore()
WriteToTraceFile("DoSomemore")
...
End Sub
' And finally...
' This is the sample code from C# dll to write to the log file. The file name is
' passed into the constructor and stored in _fileName. This is in the ApplicationFileLogger class.
public void WriteLine(String text, bool logDate)
{
// open the file for append (creates if not exist)
using (StreamWriter sw = new StreamWriter(_fileName, true))
{
// write the text and close the file
sw.WriteLine(text);
sw.Close();
}
}