Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an in-memory 'circular' logger that uses a ConcurrentQueue internally.

When an error occurs, I access the contents of the in-memory log to give additional context to the error message. It all seems to work fine.

Then I looked again at the code and began to wonder if what I had written was in fact safe, given the fact that any thread can theoretically continue to write to the log while the contents of the log are being accessed.

The basics of my code are as follows:

public class Logger
{
    public void WriteLine( string text )
    {
		_textLines.Enqueue( text );
		if( _textLines.Count > _MaxLines )
			_textLines.TryDequeue( out string discardable );
    }

    public string[] WholeLog { get { return _textLines.ToArray(); } }

	private ConcurrentQueue<string> _textLines = new ConcurrentQueue<string>();

    private const uint _MaxLines = 100;
}


public class SomeClientCode
{
    public void PrintOutContentsOfMemoryLog
    {
        foreach( string logLine in _logger.WholeLog )
            Debug.Write( logLine );
    }

    private Logger _logger = new Logger();
}

Does this look like it might cause a problem?

What I have tried:

I could increase the size of the in-memory log to a big number and then fire-up another thread and do some writing in a tight loop while the first thread attempts to print out the log, but I haven't done this test yet, mainly because I'd first like to get a sanity-check from better programmers than I.

I'm also aware that a test such as the one above might not necessarily show up a problem if I have a fundamental misunderstanding of this. I guess what I am saying really is that I'd like to learn something.
Posted
Updated 22-Feb-18 2:26am

1 solution

They hide information like that in the documentation[^]:
Quote:
The enumeration represents a moment-in-time snapshot of the contents of the queue. It does not reflect any updates to the collection after GetEnumerator was called. The enumerator is safe to use concurrently with reads from and writes to the queue.

The enumerator returns the collection elements in the order in which they were added, which is FIFO order (first-in, first-out).
 
Share this answer
 
Comments
Patrick Skelton 22-Feb-18 10:22am    
Sorry, I should have checked the documentation. I just thought I was dealing with a fundamental principle in the language. I am honestly surprised to see such a clear, to-the-point answer right there in the documentation.

I wanted to learn something and I have. The lesson is: don't have so little faith in the documentation.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900