In your situation, I don't understand why you want to use a ReaderWriterLock at all. You presumably have multiple threads adding new messages to the queue (writing), and only one (the queue flusher) that's reading. Chad's description of when you might want an WRL is right on.
As Marek pointed out, you ought not "reset the queue" unless you hold a Write lock. You should also be aware that the "stock" .NET ReaderWriterLock object implementation is very poor (in 1.x; hopefully it will be [already is?] better in 2.x). (Sources: Jeffrey Richter, Jeff Prosise.) Might I suggest an alternative design? The class you expose should have some number of static "here's a new message" methods (perhaps all overloads with the same name, some that might do formatting, or take a boolean or "severity level" that won't actually store the message [and thus won't need to do the formatting] in some cases, etc). Each of the static methods does something to turn its parameter(s) into a string and calls the version that accepts a string parameter. (Of course, the callers using the static methods aren't forced to provide any synchronization.) The class has a (private) Queue (or List or whatever) in which it stores messages. The static routine that accepts a string locks something (but not the private Queue into which it's storing) and adds the passed string to the Queue. (The locking will serialize the calls from multiple threads.) If the Queue isn't now full, it unlocks and exits; now other threads that were waiting for the lock will continue; one of them will get the lock. If the Queue is full (however that's defined; for example, it could be deemed "full" if too much time has gone by since the last message was added), it stores a reference to the current Queue in a local variable, creates a new (empty) Queue (or List or whatever), replaces the class's reference to the Queue with a reference to the new Queue, and unlocks but does not yet exit. (Now other threads will be freed up, and will add their messages in turn to the new Queue.) The method then calls the thread pool's QueueUserWorkItem to run a method to push the contents of the no-longer-being-referenced-elsewhere Queue to wherever it goes, using code like what you've got now. (When that method exits, the now-written Queue is no longer referenced and will get collected.) The reason QUWI is used is so that if it takes longer to flush the queue than to fill the new queue (which had better not happen consistently or you'll have trouble!), the work to do the queue-flushing of the multiple separate full queues will be done in sequence. At 03:11 PM 9/29/2004, Jekke Bladt wrote >All-- > >I'm having a problem with the ReadWriteLock object in .net and wondering >if I'm misunderstanding the concept: > >The class I've written manages a log that stores messages in a queue and >periodically flushes the queue to save the messages to a text file. > >In order to minimize blocking, I've written the class to copy the queue >into an array, reset the queue, and release the reader lock. There is no >place anywhere else that the queue is reinitialized or anything is >dequeued. > >And yet, I am still having a problem where, during amsg = mQueue.ToArray >is failing because the queue is empty. FileSave is never called with the >queue empty. > >I suspect there's some conceptual error here, but I'll be damned if I >can figure it out on my own. Can anyone help? > >TIA > >--Jekke >[snip] J. Merrill / Analytical Software Corp =================================== This list is hosted by DevelopMentorŪ http://www.develop.com Some .NET courses you may be interested in: Essential .NET: building applications and components with CSharp August 30 - September 3, in Los Angeles http://www.develop.com/courses/edotnet View archives and manage your subscription(s) at http://discuss.develop.com