gpt4 book ai didi

c# - 具有单个编写器的 MemoryMappedFile 是否需要同步

转载 作者:行者123 更新时间:2023-11-30 18:28:23 28 4
gpt4 key购买 nike

我有一个处理Excel文件(之前上传到服务器)的网络服务,涉及到很多数据库更新,需要相当长的时间。我想提供另一个 web 服务,可以调用它来检查这个过程的进度。它将进程的 ID(可能是 GUID)作为输入并返回一个 int (0-100) 指示进度。

我的想法是,长时间运行的服务可以创建一个内存专用的 MemoryMappedFile (MMF)——只需要 sizeof(int) 字节——它会在哪里,每隔一段时间,报告它的进展。然后,“进度”服务可以打开 MMF,读取 int,并向调用方报告。

我有两个问题。首先,我对 MMF 没有太多经验,所以这里是否有一些我可能没有意识到的陷阱?其次,更重要的是,鉴于只有一个作者,在这种情况下是否需要同步?稍作搜索后,我无法发现 MemoryMappedViewAccessor.Write 对于 int 是否是原子的。

最佳答案

一开始我不确定,因为我以前没有为 IPC 使用过 MMF,但我现在使用 the samples on MSDN 测试了它.

简短的回答是否定的,不需要同步(如果您考虑一下,这是有道理的)。您有以下两个示例 - 编写器进程和读取器进程,作为控制台应用程序。

唯一的问题是您想要在每次读/写后将写/读流中的光标位置重置为 0,或者为前 32 位创建一个 View 映射。不确定第二个是否有效(很可能无效,您仍然需要重置文件指针)。

编写器进程:

    static void Main(string[] args)
{
using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 10000))
{
int i = 0;
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
while (i++ < 10000)
{
writer.Write(i);
Thread.Sleep(50);
writer.Seek(0, SeekOrigin.Begin);
}
}
}

Console.WriteLine("Done");
Console.ReadLine();
}
}

读者进程:

    static void Main(string[] args)
{
try
{
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
{
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
using (BinaryReader reader = new BinaryReader(stream))
{
int value = 0;
while (value != 10000)
{
value = reader.ReadInt32();
Console.WriteLine("Process A says: {0}", value);
stream.Seek(0L, SeekOrigin.Begin);
Thread.Sleep(20);
}
}
}
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
}
}

我故意让读者在读取之间等待的时间少于编写者在写入之间等待的时间,以确保没有巧合。

输出符合预期,虽然没有等待它完成:

Process A says: 85
Process A says: 85
Process A says: 85
Process A says: 86
Process A says: 86
Process A says: 87
Process A says: 87
Process A says: 87
Process A says: 88
Process A says: 88
Process A says: 89
Process A says: 89
Process A says: 89
Process A says: 90
Process A says: 90
Process A says: 91
Process A says: 91
Process A says: 91
Process A says: 92
Process A says: 92
Process A says: 93
Process A says: 93
Process A says: 93
Process A says: 94

话虽如此,我仍然不推荐 MMF。根据您的描述,您可以在报告进度的服务中静态地(可能在并发集合中)存储进度而不会出现问题。您可以通过仅公开另一个端点或方法来解决此问题,第二个服务可以调用该端点或方法来更新特定客户端/文件的进度。完成后,它只是告诉它从内存中删除它。

关于c# - 具有单个编写器的 MemoryMappedFile 是否需要同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25084513/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com