VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText
VB.NET AppendAllText VB.NET AppendAllText
VB.NET AppendAllText
Go Back  Xtreme Visual Basic Talk > > > VB.NET AppendAllText


Reply
 
Thread Tools Display Modes
  #1  
Old 08-14-2009, 06:33 AM
rajeevbhatt17 rajeevbhatt17 is offline
Freshman
 
Join Date: May 2008
Posts: 38
Default VB.NET AppendAllText


Hi,

I am facing the following problem, and would like to get a suggestion on how to get around it:

We have an Exception Logging class, which uses AppendAllText to log errors into a text file. Following is the code:

Public Function ErrorLog(ByVal _strErrorText As String)
Dim oLock As New Object
Monitor.Enter(oLock)

Try
System.IO.File.AppendAllText(strAppLogFolder & strAppLogFile, _strErrorText)

Catch ex As Exception
'Either this =====> Alt A

System.IO.File.AppendAllText(strAppLogFolder & strAppLogFile.Split(".")(0) & "_" & Now.ToString("HHmmss") & ".log", _strErrorText)

'Or this =====> Alt B
'ErrorLog(_strErrorText)


End Try
Monitor.Exit(oLock)
End Function


Now everything works fine when there are a few errors to log, and there is enough time in between them, for the log file to be closed, so that when the next error comes the file is capable of being written to.

However, in case of a cascade of errors, the lock is released before the file is properly closed, so that an exception is thrown. This we have caught, and tried two alternate solutions, ALt A --> write to another file : which is not really optimal, and Alt B --> call the same function again, which works, but it is optimal.....?

My question is, is there a way to check if a file is closed properly, before using AppendAllText, to write to it?

Any help would be much appreciated

Regards
RB
Reply With Quote
  #2  
Old 08-14-2009, 10:04 AM
AtmaWeapon's Avatar
AtmaWeaponVB.NET AppendAllText AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I was going to suggest some thread synchronization code, but I noticed you already have some code you could modify to work:
Code:
Dim oLock As New Object
Monitor.Enter(oLock)
This is useless. Each time a different thread calls ErrorLog(), a new lock object is created and entered. It is *impossible* for two threads to end up with the same lock object, so there is no thread safety at all. Worse, if an exception is thrown, you don't exit the Monitor!

You should use a class-level object for this task. In addition, ErrorLog() is a poor name for the method: methods should be verbs because they do someting. "ErrorLog" is a noun and would be a better name for a class that represents an error log, which happens to be a solution to the problem:
Code:
Public Module ErrorLog
    Private ReadOnly LockToken As New Object()

    Private _logFilePath As String

    Public Property LogPath() As String
        Get
            Return _logFilePath
        End Get
        Set(ByVal value As String)
            _logFilePath = value
        End Set
    End Property

    Public Sub Append(ByVal errorText As String)
        Monitor.Enter(LockToken)

        File.AppendAllText(LogPath, errorText)

        Monitor.Exit(LockToken)
    End Sub
    
    Public Function SetPath(ByVal directory As String, ByVal fileName As String) As String
        LogPath = Path.Combine(directory, fileName)
    End Function

End Module
I would not recommend catching all exceptions in Append(). What if attempting to open the file throws an exception because the disk is out of space? If you call Append() again, you'll throw the exception again, then call Append() and so on until you throw StackOverflowException, which you'll try to catch. What a mess!

According to the documentation, these are the only exceptions you should handle: ArgumentException, ArgumentNullException, PathTooLongException, DirectoryNotFoundException, IOException, UnauthorizedAccessException, FileNotFoundException, NotSupportedException, and SecurityException. Out of those, I'd suggest handling all but ArgumentException, NotSupportedException, and ArgumentNullException; the only thing you should do when you handle each exception is indicate to the user that there is a problem with the error log and errors will not be logged. For example, here's a modification that would work:
Code:
Public Sub Append(ByVal errorText As String)
    Monitor.Enter(LockToken)

    If _didWriteErrorHappen Then
        Monitor.Exit(LockToken)
        Return
    End If

    Try
        File.AppendAllText(LogPath, errorText)
    Catch ex As IOException
        ' Handles IOException, DirectoryNotFoundException, FileNotFoundException, and PathTooLongException
        _didWriteErrorHappen = True
        DisplayLoggingError(ex)
    Catch ex As System.Security.SecurityException
        _didWriteErrorHappen = True
        DisplayLoggingError(ex)
    Catch ex As UnauthorizedAccessException
        _didWriteErrorHappen = True
        DisplayLoggingError(ex)
    Finally
        Monitor.Exit(LockToken)
    End Try
End Sub

Private Sub DisplayLoggingError(ByVal ex As Exception)
    Dim message As String
    Dim exceptionType As Type = ex.GetType()

    If exceptionType Is GetType(IOException) Then
        message = "There was an error writing to the error log file.  Any remaining errors will not be logged."
    ElseIf exceptionType Is GetType(System.Security.SecurityException) Then
        message = "The current user is not allowed by Windows to write to files.  Any remaining errors will not be logged."
    ElseIf exceptionType Is GetType(UnauthorizedAccessException) Then
        message = "The current user is not allowed by Windows to write to the error log file.  Any remaining errors will not be logged."
    Else
        message = "An unexpected error occurred while logging an error.  No further errors will be logged."
    End If

    ' Be careful!  See the post.
    MessageBox.Show(message)
End Sub
This snippet demonstrates handling the exceptions to the best of your ability. If there's an IO exception, then there was a problem writing to the file and odds are there will be an error again, so you report the error and stop writing. Same with a security exception or unauthorized access: you aren't allowed to write to the file, so there's nothing you can do.

One thing to keep in mind: I'm assuming that multiple threads are in play here; you should marshal any calls to things that rely on the UI to the UI thread or there will be problems. In my example, MessageBox.Show() will only block the thread it's on, so the message box won't block the UI thread unless something makes a synchronous call to Append() (the thread synchronization will block at that point.)
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #3  
Old 08-16-2009, 12:51 PM
rajeevbhatt17 rajeevbhatt17 is offline
Freshman
 
Join Date: May 2008
Posts: 38
Default

Thanks for the detailed reply, AtmaWeapon.....it really needs to be read and digested in peace. I will get back to you, in case I have any questions.

Thanks again,
RB
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText VB.NET AppendAllText
VB.NET AppendAllText
VB.NET AppendAllText
 
VB.NET AppendAllText
VB.NET AppendAllText
 
-->