在克服了其他一些困难之后,我现在陷入了这个(可能很简单)的问题。
我的目标:
问题是,当另一个进程已经这样做并且没有释放
The file is being used by another process
对象时,我在尝试 CreateFromFile( ) 时收到 IOException (MemoryMappedFile
)。理论上,我可以使用互斥体并使用 using
语句不断地处理对象,但这会将内容转储到磁盘,再次减慢执行速度并达不到目的。
我的问题有哪些可能的解决方案?
理论上,我可以 CreateOrOpen( ) 一个非持久化文件,然后在需要时将其转储到磁盘,但我相信有更好的方法吗?
编辑:我觉得我没有说清楚。应用程序的所有实例都需要不断处理该文件,它们打开该文件并在接下来的 10、20、60 分钟内使用该文件,而无需关闭该文件。最终所有这些都将被杀死,这时操作系统就会介入,将映射文件刷新到磁盘。
示例程序:
方案A)
static void Main(string[] args)
{
var mmf = MemoryMappedFile.CreateFromFile(@"C:\Users\admin\Documents\Visual Studio 2010\Projects\serialize\serialize\bin\Debug\File.dat", FileMode.Open, "name");
var accessor = mmf.CreateViewAccessor();
accessor.Write(5, 'd');
Console.Read();
}
方案B)
static void Main(string[] args)
{
var mmf = MemoryMappedFile.CreateFromFile(@"C:\Users\admin\Documents\Visual Studio 2010\Projects\serialize\serialize\bin\Debug\File.dat", FileMode.Open, "name");
var accessor = mmf.CreateViewAccessor();
accessor.Write(2, 'x');
Console.Read();
}
我同时运行两者,让它们挂起等待
Console.Read()
。理想情况下,他们应该能够同时访问该文件(即,他们两个都可以在另一个文件打开后打开它),但如上所述,我收到了 IOException。
这就是 MMF 的要点。
如果您想使用已在使用的文件,则需要使用
OpenExisting
而不是 CreateFromFile
。您为每个 MMF 命名。在你的情况下,你选择了"name"
。这就是你给予OpenExisting
的东西。
https://learn.microsoft.com/en-us/dotnet/api/system.io.memorymappedfiles.memorymappedfile.openexisting?view=net-8.0#system-io-memorymappedfiles-memorymappedfile-openexisting(系统字符串)
这两个进程不仅打开同一个文件,而且还共享内存。因此,该名称让系统知道要共享什么。
由于您的程序是对称的,“第一个”程序应该使用
CreateFromFile
,“第二个”程序应该使用 OpenExisting
。您可以使用 try 块首先尝试创建然后存在,以便您可以使用相同的代码。