Streamwriter and thread safety
-
I'm a little concerned about thread safety and I'm not sure how to interpret the MSDN docs in this case. I'm making use of a VB.NET Module that has a public function for the code base I am working on to log events. This logging function can be called from anywhere at any time. The code skeleton looks like;
Module Utility
...
Public Sub LogSomething(ByVal logData as string)... // do work here
Dim srLog as StreamWriter = new StreamWriter() // which opens a common file
... // finish up work here
End Sub
...
End ModuleIs this thread safe? Could this turn into an issue? The code I'm looking at hangs occasionally for no apparent reason and I'm wondering if there's any possible way this could be influencing what's happening since every thread whatever it's doing is making use of this logging function. Thanks! Neil
-
I'm a little concerned about thread safety and I'm not sure how to interpret the MSDN docs in this case. I'm making use of a VB.NET Module that has a public function for the code base I am working on to log events. This logging function can be called from anywhere at any time. The code skeleton looks like;
Module Utility
...
Public Sub LogSomething(ByVal logData as string)... // do work here
Dim srLog as StreamWriter = new StreamWriter() // which opens a common file
... // finish up work here
End Sub
...
End ModuleIs this thread safe? Could this turn into an issue? The code I'm looking at hangs occasionally for no apparent reason and I'm wondering if there's any possible way this could be influencing what's happening since every thread whatever it's doing is making use of this logging function. Thanks! Neil
I would definitely put a lock around this code. I mean, it's obvious that two threads can't have the same file open at the same time. I'd also consider opening the file once and having a lock on it for the length of the program, or doing all logging to a stringbuilder and having that dump it's contents in a try/catch as a last action before the app crashes or closes naturally.
Christian Graus Driven to the arms of OSX by Vista.
-
I would definitely put a lock around this code. I mean, it's obvious that two threads can't have the same file open at the same time. I'd also consider opening the file once and having a lock on it for the length of the program, or doing all logging to a stringbuilder and having that dump it's contents in a try/catch as a last action before the app crashes or closes naturally.
Christian Graus Driven to the arms of OSX by Vista.
I was thinking the log route myself, I'm not a big fan of doing it this way but it's mandated for me right now unfortunately. Sadly, the amount of logging that's actually thrown out there over the life of the code (services) would end up sucking up all the memory way before it dies naturally. Unfortunately when it does go wrong it doesn't crash *OR* close naturally, it's still running to all intents and purposes just hanging which is what was leading me to wonder if thread contention could be coming into play. Thanks for your response!
-
I was thinking the log route myself, I'm not a big fan of doing it this way but it's mandated for me right now unfortunately. Sadly, the amount of logging that's actually thrown out there over the life of the code (services) would end up sucking up all the memory way before it dies naturally. Unfortunately when it does go wrong it doesn't crash *OR* close naturally, it's still running to all intents and purposes just hanging which is what was leading me to wonder if thread contention could be coming into play. Thanks for your response!
NeilPrice wrote:
it's still running to all intents and purposes just hanging which is what was leading me to wonder if thread contention could be coming into play.
It's a definite possibility. Like Christian said, I'd wrap the LogSomething in a SyncLock to keep multiple threads from writing to the log at the same time. Also, since it sounds like your logging LOTS of information, I'd open the file in the first call to LogSomething and keep it open until the app closes. You can still look at the log file while the app is running, or file is open, in Notepad or some other quick'n'dirty editor that doesn't lock the file itself.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008 -
NeilPrice wrote:
it's still running to all intents and purposes just hanging which is what was leading me to wonder if thread contention could be coming into play.
It's a definite possibility. Like Christian said, I'd wrap the LogSomething in a SyncLock to keep multiple threads from writing to the log at the same time. Also, since it sounds like your logging LOTS of information, I'd open the file in the first call to LogSomething and keep it open until the app closes. You can still look at the log file while the app is running, or file is open, in Notepad or some other quick'n'dirty editor that doesn't lock the file itself.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008I wrapped a synclock around there for good measure but it turns out that was unrelated to this hanging issue I was experiencing. I think I had two lines of code outside of any kind of Try-Catch mechanism in the whole thread part of the service - it turns out apparently you have to set a variable before logging what it is :rolleyes: Just about sums up my week really, I can't believe I did that =/ On the bright side I'm a lot more confident in the logging part of the code now anyway ;) Thanks for your input!
-
I wrapped a synclock around there for good measure but it turns out that was unrelated to this hanging issue I was experiencing. I think I had two lines of code outside of any kind of Try-Catch mechanism in the whole thread part of the service - it turns out apparently you have to set a variable before logging what it is :rolleyes: Just about sums up my week really, I can't believe I did that =/ On the bright side I'm a lot more confident in the logging part of the code now anyway ;) Thanks for your input!
Hi, IMO logging should be inexpensive and as real-time as possible, hence buffering, locking, thread switching are to be avoided. I tend to open-append-close for each individual log message, since the last message before the app dies is probably the one you want to catch most of all. The good news is File.AppendAllText() is a static and thread-safe method that does exactly that: open-append-close without unnecessary hassle. It does perform security checks over and over, so you'd better log to a local file without special security issues. BTW: if you want to add an option to e-mail your log file from within the app, you really need to copy it first, otherwise mailing it and continuing to log would interfere... :)
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets