|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Known Issues w/ File.AppendText()method. I'm trying to write data to a log file using it and I'm having some issues. I keep getting an error message from my ProcessException() handler saying "The process cannot access the file 'C:\Temp\Logging\LogFileX.log' because it is being used by another process. Here is my code I was using. Previously I was using a Using statement for the StreamWriter (sw)... Private Sub WriteDataToFile(ByVal FileName As String, ByVal DataString As String) Dim sw As StreamWriter = File.AppendText(FileName) Try If File.Exists(FileName) Then 'Using sw As StreamWriter = File.AppendText(FileName) sw.WriteLine(DataString) 'sw.Flush() 'Update text to file. sw.Close() 'Close StreamWriter and underlying file. 'End Using Else Throw New FileNotFoundException End If Catch ex As Exception sw.Close() 'Close StreamWriter and underlying file. Common.Instance.ProcessException(Common.Instance.CurrentMethodName(), ex) End Try End Sub I am using File.Exist() Shared method and FileInfo objects to see if the file exist and to check the file size, etc. Could these cause problems writing to the file? I am writing a lot of messages to the my .log file using a loop in a test project. I seem to get this error message while initially writing a message to the file and when I create a new .log file. When I write to a new .log file it will skip 5 to 8 lines of text between files. Basically when my current .log file reaches maxium size it will create a new file and start writing to it; LogFile1.log, LogFile2.log, LogFile3.log, etc. I have a more elabrate naming conventation with data/time data but I simplified it here. Is there a better way to write to a log file besides this File.AppendText()? I don't believe I was initially getting this error message. But I was not trapping for it or looking for it either. I normally will not be writing to the log file this fast but for testing purposes I am writing in a loop some test messages and it is fast. I tried to add some Thread.Sleep() between 2 and 100 milliseconds but that only seems to work a little in places. I then put a Thread.Sleep between each time I write to log file and still getting the error message. Help! JerryM JerryWEC <JerryWEC@newsgroups.nospam> wrote:
> I'd like to know if there are any known issues with using AppendText() And was it working then? Currently you're not closing the file unless > method. I'm trying to write data to a log file using it and I'm having some > issues. I keep getting an error message from my ProcessException() handler > saying "The process cannot access the file 'C:\Temp\Logging\LogFileX.log' > because it is being used by another process. > > Here is my code I was using. Previously I was using a Using statement for > the StreamWriter (sw)... an exception is thrown - which means next time you try to write to the file, it won't be able to unless the underlying Stream's finalizer happens to have been called already to release the file handle. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Jon, I'm calling sw.Close() within the If statement and In the trap. In
this case I always have a file the If statement was for good measure when I was using the Using statement (which I thought closed the object explicitly anyway). I'm using the following code as well... Private Sub LogMessageToFile(ByVal strErrorMessage As String) Try 'Step 1 - Set File Path and File Name. If CurrentLogFilePathAndName = String.Empty Then CurrentLogFilePathAndName = BuildFileName() 'Build initial file name. Thread.Sleep(500) End If 'Step 2 - If File is at Max Size create another file, otherwise use it. If FileIsAtMaxSize(CurrentLogFilePathAndName) Then ''''''''' This method is using the FileInfo object and File.Exist(). Thread.Sleep(500) CurrentLogFilePathAndName = BuildFileName() 'Build a new file name. Thread.Sleep(500) End If 'Step 3 - Write Msg to File. WriteDataToFile(CurrentLogFilePathAndName, strErrorMessage) 'Step 4 - If File is over Max Files the Delete Oldest File. DeleteOldestFile() 'Step 5 - Refresh File List. *** Moved to PostMessage()! Catch ex As Exception 'Raise Event in ProcessException!!! Refer to old VB6 code. Common.Instance.ProcessException(Common.Instance.CurrentMethodName(), ex) End Try End Sub I added the Thread.Sleep()'s to make sure everything is closed. I don't see where I am doing anything wrong. I also put in a Thread.Sleep() before my code in the WriteDataToFile () (Step 3). I have a property called CurrentLogFilePathAndName which creates the file when assigned a new file name using... If Not File.Exists(value) Then File.Create(value) End If I don't see what I'm doing wrong. Any help is greatly apprecaited! JerryM JerryWEC <JerryWEC@newsgroups.nospam> wrote:
> Jon, I'm calling sw.Close() within the If statement and In the trap. Ah, sorry, I didn't notice the first one.> In this case I always have a file the If statement was for good measure when I Yes, the Using statement will close it already. I don't see why you > was using the Using statement (which I thought closed the object explicitly > anyway). thought you needed the "If" even when you were using the Using statement though. > I'm using the following code as well... <snip>> I added the Thread.Sleep()'s to make sure everything is closed. I don't see That last bit may well be the problem. File.Create returns a > where I am doing anything wrong. I also put in a Thread.Sleep() before my > code in the WriteDataToFile () (Step 3). I have a property called > CurrentLogFilePathAndName which creates the file when assigned a new file > name using... > > If Not File.Exists(value) Then > > File.Create(value) > > End If > > I don't see what I'm doing wrong. Any help is greatly apprecaited! JerryM FileStream, which you're not closing. Try closing it, and see if that gets rid of the problem. Note that you'll always have a race condition there - if two threads both notice that the file isn't there, they could both call Create even though one will "win" and get there first. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Jon, thank you for discovering my problem! It was the FileStream object!
After I closed it all was well. Jeffrey, I did download the tool you were talking about but I have not had time to use it yet. I believe it will be a useful tool. I have needed this type of tool in TS issues in the past. I have since have modified the code (with Jon's help) and got it working well. However, I had a conversation with my boss and he wants me to keep the StreamWriter open while the file has not reached it's max size. (I switched from a File.Create() to File.CreateText() object to create the file). I have this working with a private variable and private property to hold my StreamWriter object. However, I'm having problems closing the last file. I have implemented the IDisposable interface with a Finalize and two Dispose methods. I have a private variable to hold the disposed flag (boolean). I am not calling the Dispose(True) method directly which is my problem. Where should I call my Dispose(True) method to close my last file? I will start a new thread to solve this problem if no one can help me here. Note: I just called the public .Dispose() method from my test project and it did do the disposing explicitly. However, I really would like to have this handle with out my users having to call .Dispose(). How should I close the last file when I don't know when the user is finished with my Logging object? The Logging object is the class my test project is using. Help! :) Thanks in advance!!! JerryM . JerryWEC <JerryWEC@newsgroups.nospam> wrote:
<snip> > Note: I just called the public .Dispose() method from my test project and it They should do it explicitly - the "using" statement will help to do it > did do the disposing explicitly. However, I really would like to have this > handle with out my users having to call .Dispose(). How should I close the > last file when I don't know when the user is finished with my Logging > object? The Logging object is the class my test project is using. Help! :) automatically. If they don't call Dispose, they'll have to wait for the finalizer to kick in. However, you don't need to have a finalizer yourself - the underlying Stream will have a finalizer which will work just as well. (And indeed, by the time your finalizer is invoked, the Stream's one may already have been invoked.) -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Jon, thanks for the info!
Are there any good resources that talk about how these StreamWriter & FileStream classes work like if you have a sw object and you have not closed the object does that mean the file is still open? I'm looking for that level of information. When you have a class that you created (class library) what is the best way to close files open using dispose / finalize / finalizer? I have this working but it just seems a bit to busy for normal explicit destruction of managed objects. I can see doing it for unmanaged objects. But if you need to make sure you close an object or deterministly destroy an object ms way seems over kill? JerryM Hi Jerry,
Thanks for your feedback. There are not many dedicated articles talking about StreamWriter and FileStream. The best way to understand these 2 classes internal is using Reflector tool to view the source code of these 2 classes. You may free download the Reflector in the link below(this is the must have tool to view all .Net BCL assemblies source code): http://www.aisto.com/roeder/dotnet/ However, there are still one MSDN article and one blog entry talking about best practice of clearup StreamWriter and FileStream: "Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework" http://msdn.microsoft.com/msdnmag/issues/1100/gci/ "StreamWriter Buffered Data Lost MDA (or a cute finalizer trick) [Brian Grunkemeyer]" http://blogs.msdn.com/bclteam/archive/2004/08/13/214405.aspx Note: in first "Jeffrey Richter"'s MSDN article, "Forcing an Object to Clean Up" section is dedicated for FileStream and StreamWriter cleanup, although I recommend you also read all other sections of this article because they are the best resource for Garbage Collection topic. After you read these 2 articles, I am sure you will understand it better. I will provide some more comment below: 1. There is no need for you to implement IDisposable interface, both StreamWriter and FileStream have implemented IDisposable interface. For example, you may use Reflector to view StreamWriter.Close method source code, I listed below: //Close method normally calls Dispose(disposing) method to do the internal work. public override void Close() { this.Dispose(true); GC.SuppressFinalize(this); } //Flush the data buffer and close the file handle protected override void Dispose(bool disposing) { try { if ((this.stream != null) && (disposing || (!this.Closable && (this.stream is __ConsoleStream)))) { this.Flush(true, true); .... } } finally { if (this.Closable && (this.stream != null)) { try { if (disposing) { this.stream.Close(); } } finally { .... base.Dispose(disposing); } } } } You may also view FileStream's Close, Dispose methods source code. 2. As stated in "Jeffrey Richter"'s article, after you used StreamWriter to wrap FileStream in constructor(see below), you should only call StreamWriter.Close method; this method internally will call FileStream.Close for you. StreamWriter sw = new StreamWriter(fs); 3. Yes, once you use StreamWriter to wrap one disk file, StreamWriter will lock this file for only sharing read not write. This means another code snippet can not use another FileStream/StreamWriter to open this file for write again. Internally, StreamWriter will always wrap a FileStream for that file even you do not explicit create a FileStream. You may use Reflector to view source code to confirm this: //the pure string path constructor calls another more parameter constructor public StreamWriter(string path) : this(path, false, StreamWriter.UTF8NoBOM, 0x400) { } //This constructor is called by other constructors public StreamWriter(string path, bool append, Encoding encoding, int bufferSize) : base(null) { if ((path == null) || (encoding == null)) { throw new ArgumentNullException((path == null) ? "path" : "encoding"); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); } Stream stream1 = StreamWriter.CreateFile(path, append); this.Init(stream1, encoding, bufferSize); } //Yes, StreamWriter.CreateFile method internally will create a FileStream for usage private static Stream CreateFile(string path, bool append) { FileMode mode1 = append ? FileMode.Append : FileMode.Create; return new FileStream(path, mode1, FileAccess.Write, FileShare.Read, 0x1000, FileOptions.SequentialScan); } Note: when creating FileStream, .Net will pass FileShare.Read to share read operation with other code not write operation. 4. Yes, if your boss wanted to keep the StreamWriter open before file has reached its max size, you may store this StreamWriter in a variable and always use this StreamWriter reference to append to the log file. Note: during this period, you can not create another FileStream or StreamWriter to write to the same log file, because the original StreamWriter locks this file now. After the log file reaches its max size, you may call StreamWriter.Close to close the handle. If you still have anything unclear, please feel free to feedback. Thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Wow! Jeffrey thank you so much!
Comment #4 is what I am doing now. My only concern is I would like to explicitly close the StreamWriter object on the last file. (StreamWriter.Close()) From your previous post I'd say the file is automatically being closed? I will read the references you provided. I really appreciate all the information you provided me! Typically, I would just open, write and close the StreamWriter but powers to be would like to keep the file locked until finished. (Hopefully this will be faster anyway.) I will check out all your references and that tool this weekend. I have to go code now. :) Super responses Jon and Jeffrey!!! JerryM Jeffrey,
After reading all of the reference material you provided me I believe I do need to do a Close() / Dispose() method to explicitly close my StreamWriter object and under lying file (internal FileStream). Basically in my code below I create a StreamWriter object in side a property when a new file name is built. The controlling application has control of this creating of files through my class library called CLA_Logging. I create the file using a File.CreateText() which returns the StreamWriter object which is used for all files (See StreamWriter property). I explicitly close the previous StreamWriter before reusing the variable again. Here's the issue I see. I need to be able to explicitly close the last StreamWriter object as the class object is being distoryed (GC) or at end of lifetime. I have created a Dispose() method that is called in the calling application. This seems to work fine. I may have to modify it to make it work if the application programmer does not call Dispose() method. I'll want to have the GC finalize the object and call my Dispose method. I added the code below to help understand my line of thinking... Private Property StreamWriter() As StreamWriter Get Try Return m_StreamWriter Catch ex As Exception ProcessException(CurrentMethodName(), ex) Return Nothing End Try End Get Set(ByVal value As StreamWriter) Try If m_StreamWriter IsNot Nothing Then m_StreamWriter.Close() 'Close last stream writer object before re-using... End If m_StreamWriter = value Catch ex As Exception ProcessException(CurrentMethodName(), ex) End Try End Set End Property Private Property CurrentLogFilePathAndName() As String Get Try Return m_CurrentLogFilePathAndName Catch ex As Exception ProcessException(CurrentMethodName(), ex) Return Nothing End Try End Get Set(ByVal value As String) Try If Not File.Exists(value) Then StreamWriter = File.CreateText(value) End If m_CurrentLogFilePathAndName = value m_formInstance.lblLogFile.Text = m_CurrentLogFilePathAndName Catch ex As Exception ProcessException(CurrentMethodName(), ex) End Try End Set End Property Private Sub WriteDataToFile(ByVal FileName As String, ByVal DataString As String) Try If File.Exists(FileName) Then StreamWriter.WriteLine(DataString) StreamWriter.Flush() 'Update text to file. Else 'If file is not found the create a new one... CurrentLogFilePathAndName = BuildFileName() 'Build a new file name. StreamWriter.WriteLine(DataString) StreamWriter.Flush() 'Update text to file. End If Catch ex As Exception ProcessException(CurrentMethodName(), ex) End Try End Sub ' Implement IDisposable. ' Do not make this method virtual. ' A derived class should not be able to override this method. Public Overloads Sub Dispose() Implements IDisposable.Dispose Dispose(True) ' This object will be cleaned up by the Dispose method. ' Therefore, you should call GC.SupressFinalize to ' take this object off the finalization queue ' and prevent finalization code for this object ' from executing a second time. GC.SuppressFinalize(Me) End Sub ' Dispose(bool disposing) executes in two distinct scenarios. ' If disposing equals true, the method has been called directly ' or indirectly by a user's code. Managed and unmanaged resources can be disposed. ' If disposing equals false, the method has been called by the runtime from inside ' the finalizer and you should not reference other objects. ' Only unmanaged resources can be disposed. Private Overloads Sub Dispose(ByVal disposing As Boolean) ' Check to see if Dispose has already been called. If Not Me.m_disposed Then '<-- Only Dispose Once!!! ' If disposing equals true, dispose all managed and unmanaged resources. If disposing Then ' Dispose managed resources here... If m_StreamWriter IsNot Nothing Then m_StreamWriter.Close() 'Close the last open file. End If End If ' Call the appropriate methods to clean up unmanaged resources here... ' If disposing is false, only the following code is executed. ' *** No Unmanaged Code Yet. End If m_disposed = True End Sub ' This finalizer will run only if the Dispose method does not get called. ' It gives your base class the opportunity to finalize. ' Do not provide finalize methods in types derived from this class. Protected Overrides Sub Finalize() ' Do not re-create Dispose clean-up code here. ' Calling Dispose(false) is optimal in terms of ' readability and maintainability. Dispose(False) MyBase.Finalize() End Sub I'm thinking I can change my Finalize() method's call from Dispose(False) to Dispose(True) to force the m_StreamWriter.Close() if called by GC. Or, Modify my Private Dispose() method as follows... Private Overloads Sub Dispose(ByVal disposing As Boolean) If disposing Then If m_StreamWriter IsNot Nothing Then m_StreamWriter.Close() 'Close the last open file. End If End If End Sub In this case I can get rid of the disposing and disposed flags all together. Food for thought. All input is good! JerryM Note: I added the code here from notepad. I have not been able to add code directly from VS2005 without having line formating problems. Looks like extra spacing under each line of text. (Issue with this News Group paste command?) Hi Jerry,
Thanks for your feedback. Yes, this is an interesting question: why StreamWriter's Dispose(disposing) does not flush the internal data buffer if disposing parameter is false(calls by GC finalizer thread)? This will cause the file stream data loss if the developer forgets to call Dispose/Close methods explicitly, which looks a strange design. Actually, the reason is discussed in the second article I provided you: http://blogs.msdn.com/bclteam/archive/2004/08/13/214405.aspx If the FileStream is called by GC finalize first, the underlying file is closed, then if the StreamWriter is called by GC finalize in a later time, the dispose method will write to a closed file. The problem arises. The GC has no knowledge of the order of finalize, so StreamWriter's Dispose(false) implementation does not flush the buffer for us. So we should always call Dispose/Close methods explicitly for StreamWriter. For other class implementation, there is no need to distinguish "disposing" paramete; we should always release the unmanaged resource in Dispose(disposing) for both true and false. You may use Reflector to view Bitmap , Mutex class or other classes without StreamWriter&FileStream dependency issue, their Dispose(disposing) just release the unmanaged resource without checking disposing parameter. So, yes, your Dispose(disposing) method shoud always close the StreamWriter whatever disposing is true or false. In Finalize() method, you may also call Dispose(False). This is a more elegant implementation. If you still have anything unclear, please feel free to tell me, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Jeffrey, two questions left...
1] Where can I find Reflector? 2] When I called Dispose(True) from my Finalizer() it threw up this exception... [1st Time] System.ObjectDisposedException was unhandled Message: Cannot access a closed file. [2nd Time] System.ObjectDisposedException was unhandled Message="Cannot access a closed file." ObjectName="" Source="mscorlib" StackTrace: at System.IO.__Error.FileNotOpen() at System.IO.FileStream.Flush() at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) at System.IO.StreamWriter.Dispose(Boolean disposing) at System.IO.StreamWriter.Close() at CLA_Logging.Logging.Dispose(Boolean disposing) at CLA_Logging.Logging.Finalize() Which makes sense to me because the FileStream object did close the file. I was AutoFlushing the StreamWriter object so all of my data was written to file. I just don't like the fact that you can't implicitly dispose of your own objects in order to close a file that is still open. Does the StreamWriter object Dispose() of the StreamWriter which calls the internal FileStream object? I guess I'm still a little unsure how the StreamWriter is working. Maybe the Reflector will help me understand. Above [2nd Time] exception is show's FS being Flushed but the file is already closed. So how did this file get closed if the Dispose() or Close() was not explicitly called? ??? JerryM Hi Nick,
Thanks for your feedback. #1, Where can I find Reflector? I have already provided the link in my second reply, maybe you missed it :-). You may free download the Reflector in the link below(this is the must have tool to view all .Net BCL assemblies source code): http://www.aisto.com/roeder/dotnet/ #2, ObjectDisposedException Yes, this exception is expected. It seems that you closed FileStream before StreamWriter. I think you missed my #2 in the second reply. I paste it below for your reference: "2. As stated in "Jeffrey Richter"'s article, after you used StreamWriter to wrap FileStream in constructor(see below), you should only call StreamWriter.Close method; this method internally will call FileStream.Close for you." So, you should not call FileStream.Close/Dispose methods, because StreamWriter still needs it. You should always call StreamWriter.Close, which closes FileStream either for you. Hope this is clear to you now. If anything unclear, please feel free to tell me, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Jeffrey, thanks for the Reflector link I did miss it. [sorry]
On the #2 issue, I am not closing the FileStream myself. I'm not even closing the StreamWriter object, which is my problem. Because I don't know when the last time the file is being used (written), I need to close the last file on destruction of the object. Right now the user's of my DLL will have to call Dispose(). I may create a .Close() method for them as well. I was hoping that I could have the Finalizer clean up this last file. The only reason I'm doing this code this way is my boss is wanting me to keep the files opened and locked until each one has reached the max size. I would not have this issue if I open, wrote to file, and then closed the file. Note: When I put Dispose(True) inside my finalizer the Dispose method was trying to close the file (using StreamWriter object), but it was already cleaned up or GC. I'm going to research how the Reflector works on this StreamWriter object. Maybe it can shed some light on the subject for me. I am doing a AutoFlush on each StreamWriter object so the data looks like it is not getting lost. Does the Reflector show you the code in VB as well as C#? I'm assuming just C#. I my have to look at this Reflector code a while. Jeffrey, thanks for all your help!!! I have learn a great deal! JerryM This Relector tool is very cool! Once you find your methods your looking
at. thanks again! JerryM Hi Jerry,
Thanks for your further information! Yes, I see the problem more clear now. Actually, this further problem is caused by the same reason as the GC finalizer dependency issue. Your class' Finalizer calls StreamWriter's Dispose(true) to close the underlying FileStream. However, the FileStream object may cleaned by the GC first, so FileStream's Finalize method is already called to close the underlying file. Once the GC calls your class's Finalize method, your methods calls StreamWriter.Dispose(true), which closes the the FileStream a second time. Then the ObjectDisposedException is thrown. So your finalize method should not call StreamWriter.Dispose method to help the developer to close the StreamWriter/FileStream. Yes, I see you want to research on StreamWrtier that how does .Net FCL resolves this Finalize dependency issue for StreamWrtier. Actually, the answer is already discussed in the article below: http://blogs.msdn.com/bclteam/archive/2004/08/13/214405.aspx That is: StreamWrtier does not do anything to resolve this problem. StreamWrtier will not close the underlying FileStream if you forget to invoke its Dispose method explicitly. The principle here is that Microsoft always requires you to invoke Dispose()/Close() method instead of relying on the Finalizer, or all the buffered data may be lost. Finally, I am sure you have discovered that Reflector can help you to view the source code in all the languages, C#, VB.net, IL etc... :-) If you need further help, please feel free to post, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Jeffrey, sorry for being such a pest! (Thanks a bunch!)
Normally and in the future all of my StreamWriter objects will be used with a using statement or at least I will write to the file and then Close() the StreamWriter object. (My preferred way to do it anyway.) I am doing the AutoFlush = True for each StreamWriter object and this seems to flush all of the data to the file anyway. I was doing a manual Flush() after each WriteLine(). Is there any speed advantage of AutoFlush over individual Flush() calls? Happy Holidays and a Merry Christmas to all! JerryM Hi Jerry,
No, you are a nice customer, I am glad to work with you. Setting AutoFlush to true has the same effect of calling StreamWriter.Flush() method after each StreamWriter.Write() operation. If you use Reflector to examine all the overloading StreamWriter.Write() methods, you will find the following statement at the end: if (this.autoFlush) { this.Flush(true, false); } However, I do not recommend setting AutoFlush=ture, since it will disable the data buffer of StreamWriter. Delay writing bufferring of StreamWriter is helpful to improve StreamWriter.Write() method performance, because multiple StreamWriter.Write() operations can be combined in a single disk write. Disk I/O is a slow operation comparing to the memory operation, so fewer I/O writting with data bufferring will yeild better performance. Merry Christmas to you and have a good new year :-) Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Jeffrey, the following code does a check to see if autoFlush is equal to
true so that was why I was asking if there is any speed advantage of using autoFlush. I want to flush the data to the file as soon as I can because I'm not sure which file or file write will be the last one. Under normal operations this logging dll will not be writting to the file that much. Currently I'm writing a lot of messages in a loop every time I click a button but normally this module will write messages with error's occur and hopefully that is few and far between. Reference: if (this.autoFlush) { this.Flush(true, false); } Thanks Again! JerryM Hi Jerry,
Yes, in your scenario, I think setting AutoFlush property to true should meet your need. If you need further help, please feel free to post, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Jerry,
Thanks for your further information. First, are you sure that there is no other processes locking your log files? To ensure this, I recommend you download "Process Explorer" from the link below: http://www.microsoft.com/technet/sysinternals/ProcessesAndThreads/ProcessExp lorer.mspx In Process Explorer, you may select "Find"->"Find Handle or DLL...(Ctrl+F)" and input "LogFileX.log" filename for searching. If any process is locking this log file, there will be an open handle to this file. This is my favorite way of finding out which process is locking a file. If Process Explorer reporting that all the open handles to the log file are in your application, it means it is threads in your appllication that lock the file. In this scenario, can you tell me do you use multithreads to access the log files? Thread.Sleep() method will delay the current thread execution for a period, it is only useful for multithreading scenario. If there is only a single thread accessing the log file, Thread.Sleep() will take no effect, because all the methods/properties in this thread execute synchronously. As Jon pointed out, do you close the FileSystem returned by File.Create method? This may place a lock over the log file which makes the file not accessible to other code/thread. Additionally, if you see non-closed file handle in your application in Process Explorer after normal operation, it means there is file handle leak in your application(you forget to close certain file stream for that file). Finally, if you still can not find out the root cause, is it possible for you to create a little sample application to reproduce this problem? This will be easier for us to troubleshoot this problem. Thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||