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.IOExc eption: The process cannot access the file '\\DEVMACH\Sand box\BLAH.log' because it is being used by another process.
at System.IO.__Err or.WinIOError(I nt32 errorCode, String maybeFullPath)
at System.IO.FileS tream.Init(Stri ng path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIB UTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileS tream..ctor(Str ing path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.Strea mWriter.CreateF ile(String path, Boolean append)
at System.IO.Strea mWriter..ctor(S tring path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.Strea mWriter..ctor(S tring path, Boolean append)
at TEST.CommonLibr ary.MYAPP.Appli cationFileLogge r.WriteLine(Str ing text, Boolean logDate)
at TEST.MYAPP.Serv ices.Processing Service.MyProce ssingService.Do Processing()
' This is the in the service onstart event
_logFile = New ApplicationFile Logger("\\DEVMA CH\Sandbox\BLAH .log")
m_timer = New System.Timers.T imer(5000)
AddHandler m_timer.Elapsed , AddressOf Timer_Tick
m_timer.Enabled = True
m_timer.Start()
GC.KeepAlive(m_ timer)
WriteToTraceFil e("The service has started.", .LogMaximum)
' end
' 1 wrapper to log to the text file - this is a seperate DLL
Private Sub WriteToTraceFil e(ByVal text As String)
_logFile.WriteL ine(text, True)
End Sub
Private Sub Timer_Tick(ByVa l sender As Object, ByVal e As System.Timers.E lapsedEventArgs )
Try
m_timer.Enabled = False
DoSomething()
Catch ex As Exception
WriteToTraceFil e("The application has hit an exception")
Finally
m_timer.Enabled = True
End Try
End Sub
Private Sub DoSomething()
WriteToTraceFil e("DoSomething" )
DoSomemore()
End Sub
Private Sub DoSomemore()
WriteToTraceFil e("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 ApplicationFile Logger class.
public void WriteLine(Strin g text, bool logDate)
{
// open the file for append (creates if not exist)
using (StreamWriter sw = new StreamWriter(_f ileName, true))
{
// write the text and close the file
sw.WriteLine(te xt);
sw.Close();
}
}
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.IOExc eption: The process cannot access the file '\\DEVMACH\Sand box\BLAH.log' because it is being used by another process.
at System.IO.__Err or.WinIOError(I nt32 errorCode, String maybeFullPath)
at System.IO.FileS tream.Init(Stri ng path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIB UTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileS tream..ctor(Str ing path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.Strea mWriter.CreateF ile(String path, Boolean append)
at System.IO.Strea mWriter..ctor(S tring path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.Strea mWriter..ctor(S tring path, Boolean append)
at TEST.CommonLibr ary.MYAPP.Appli cationFileLogge r.WriteLine(Str ing text, Boolean logDate)
at TEST.MYAPP.Serv ices.Processing Service.MyProce ssingService.Do Processing()
' This is the in the service onstart event
_logFile = New ApplicationFile Logger("\\DEVMA CH\Sandbox\BLAH .log")
m_timer = New System.Timers.T imer(5000)
AddHandler m_timer.Elapsed , AddressOf Timer_Tick
m_timer.Enabled = True
m_timer.Start()
GC.KeepAlive(m_ timer)
WriteToTraceFil e("The service has started.", .LogMaximum)
' end
' 1 wrapper to log to the text file - this is a seperate DLL
Private Sub WriteToTraceFil e(ByVal text As String)
_logFile.WriteL ine(text, True)
End Sub
Private Sub Timer_Tick(ByVa l sender As Object, ByVal e As System.Timers.E lapsedEventArgs )
Try
m_timer.Enabled = False
DoSomething()
Catch ex As Exception
WriteToTraceFil e("The application has hit an exception")
Finally
m_timer.Enabled = True
End Try
End Sub
Private Sub DoSomething()
WriteToTraceFil e("DoSomething" )
DoSomemore()
End Sub
Private Sub DoSomemore()
WriteToTraceFil e("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 ApplicationFile Logger class.
public void WriteLine(Strin g text, bool logDate)
{
// open the file for append (creates if not exist)
using (StreamWriter sw = new StreamWriter(_f ileName, true))
{
// write the text and close the file
sw.WriteLine(te xt);
sw.Close();
}
}
Comment