如何更新.Net中的内存映射文件中的值

时间:2012-05-22 03:22:41

标签: c# .net c#-4.0

我有一个代理进程,许多客户端应用程序将使用.Net远程连接。我想通过使用一些引用计数方案来管理这个代理的存在。为此,我想我会使用一个小的内存映射文件,在其中我将存储一个键值(string-int)对,它看起来像这样:

  

ref_count 2

但是,我想不时更新ref_count值,但我遇到了这样的问题。这是我的代码:

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();
        }
    }
}

所以,我的问题是,更新引用计数的最佳方法是什么,以及为什么我的第二次写入在上面的代码示例中不起作用?

谢谢,

2 个答案:

答案 0 :(得分:1)

这是一个流。因此,从它的阅读推进了立场。你需要添加

  stream.Position = 0;

在更新计数的代码和再次读取它的代码之前。通过不写字符串进一步改善它,你不需要它。

答案 1 :(得分:1)

第二次写入调用工作 - 但您正在写入/读取"错误"位置。

完成所有这些后,你应该有内存:

5("代码的长度:") "代码:" ("代码的实际字符:") 3(你写的/阅读的价值) 5(代码长度"代码:") "代码:" ("代码的实际字符:") 30(你写的价值) 0(你读的空字符串的长度) 0(你读过的值)

对任何BinaryReader / BinaryWriter方法的每次调用都在推进底层Stream。它是第一次工作,因为您在内存映射文件的视图上构造了一个新流(从而重置了Stream)。尝试在write和read之间调用stream.Seek(0L,SeekOrigin.Begin),看看会发生什么。