简体   繁体   中英

Writing data to a buffer and reading data from a buffer

I am currently looking into writing a program in c# which deals with managing log files. The purpose is the log file shouldn't exceed 50mb so I am renaming the file and creating a new and then it should start writing to the new file. To avoid data being written to the log while the files are changed I was thinking that in one part of the program I add the data to a buffer, then in another part of the program it reads the data in the buffer and outputs it to the file. If it can't write to the file it keeps it in the buffer until it can write to the file.

How would I go about doing this I can't seem to find anything on Google not sure if I'm searching the correct thing.

Thanks for any help you can provide

This sounds like a classical producer consumer problem. This is good starting points.

Blocking Collection

As other have pointed using a library is better rather than re-inventing the wheel. Log4net is a good Logging library.

I would suggest using a BlockingCollection . Threads that want to write to the log just enqueue the log string to the BlockingCollection . A separate thread monitors the BlockingCollection , de-queuing strings and writing them to the file. If the file isn't available, the thread can wait and try again.

See http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=821 for some simple examples.

If you can't use BlockingCollection , you can use a Queue and protect it with a lock. Your method to log something becomes:

private Queue<string> myQueue = new Queue<string>();  // owned by the logger

void WriteLog(string s)
{
    lock (myQueue)
    {
        myQueue.Enqueue(s);
    }
}

The thread that removes things can get them from the queue. It'll be a little less than ideal because it'll have to poll periodically, but it shouldn't be too bad:

while (!shutdown)  // do this until somebody shuts down the program
{
    while (myQueue.Count > 0)
    {
        lock (myQueue)
        {
            string s = myQueue.Dequeue();
            // write the string s to the log file
        }
    }
    Thread.Sleep(1000); // sleep for a second and do it again.
}

There are ways to do that without the busy waits, but I don't remember the implementation details. See http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulse.aspx for a sample.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM