Pat Mustard
Pat Mustard

Reputation: 1902

How do I update valued in a Memory Mapped File in .Net

I have a proxy process which a number of client applications will connect to using .Net remoting. I would like to manage this proxy's existence by using some reference counting scheme. To do this I thought I would use a small Memory Mapped File in which I will store a key-value (string-int) pair which will look something like this:

ref_count 2

However, I would like to update the ref_count value from time to time but I'm having problems doing so. Here is my code:

using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 100))
        {
            bool mutexCreated;
            Mutex mutex = new Mutex(true, "testmapmutex", out mutexCreated);
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryWriter writer = new BinaryWriter(stream);
                writer.Write("count:");
                writer.Write(3);
            }
            mutex.ReleaseMutex();

            mutex.WaitOne();
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryReader reader = new BinaryReader(stream);
                BinaryWriter writer = new BinaryWriter(stream);

                Console.WriteLine("String value is: {0}", reader.ReadString()); 
                Console.WriteLine("UInt32 value is: {0}", reader.ReadUInt32()); 

                // Update mmf data
                writer.Write("count:");
                writer.Write(30);

                // empty string where "count" was expected
                Console.WriteLine("String value is: {0}", reader.ReadString());
                // 0 where 30 was expected
                Console.WriteLine("UInt32 value is: {0}", reader.ReadUInt32()); 
            }
            mutex.ReleaseMutex();
        }
    }
}

So, my question is, what is the best way to update my reference count and also, why does my second write not work in the above code example?

Thanks,

Upvotes: 0

Views: 1533

Answers (2)

Jason
Jason

Reputation: 356

The second Write calls work - but you're writing/reading from the "wrong" location.

After all this is done, you should have in memory:

5 (length of "code:") "code:" (the actual characters for "code:") 3 (value you wrote/read) 5 (length of "code:") "code:" (the actual characters for "code:") 30 (value you wrote) 0 (length of the empty string you read) 0 (value you read)

Each call to any of the BinaryReader/BinaryWriter methods is advancing the underlying Stream. It works the first time because you constructed a new stream on the view of the memory mapped file (thus resetting the Stream). Try calling stream.Seek(0L, SeekOrigin.Begin) between the write and the read and seeing what happens.

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941208

It is a stream. So reading from it advances the Position. You'll need to add

  stream.Position = 0;

both before the code that updates the count and the code that reads it again. Further improve it by not writing the string, you don't need it.

Upvotes: 1

Related Questions