0

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

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

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

谢谢,

4

2 回答 2

1

第二个 Write 调用工作 - 但您正在从“错误”位置写入/读取。

完成所有这些之后,您应该在内存中拥有:

5(“代码:”的长度)“代码:”(“代码:”的实际字符)3(您写入/读取的值)5(“代码:”的长度)“代码:”(“代码:”的实际字符) code:") 30 (你写的值) 0 (你读的空字符串的长度) 0 (你读的值)

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

于 2012-05-22T04:07:55.517 回答
1

它是一条溪流。因此,从中读取会推进职位。您需要添加

  stream.Position = 0;

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

于 2012-05-22T03:56:50.407 回答