内存映射文件:持久化和进程间通信
MemoryMappedFiles: persistance and inter process communication
内存映射文件有问题。
1) 每次我请求一个文件(同名),我似乎得到一个新文件。我写的字节在下次访问时不存在。我只是设法通过持久化对象来解决这个问题,我认为不应该需要它。
2) 至于进程间通信,我似乎也总是为我拥有的2个进程获得2个不同的mmf对象,至少我没有看到另一个进程的变化。
两个进程之间的文件名相同,并且在连续调用之间保持相同。
代码略有修改 http://www.abhisheksur.com/2012/02/inter-process-communication-using.html .
if 条件中的 "read" 参数及其背后的代码也没有任何改善。
MemoryMappedFile file = null;
private MemoryMappedFile GetMemoryMapFile(bool read)
{
if (file != null)
return file;
var security = new MemoryMappedFileSecurity();
var everyone = new System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.WorldSid, null);
//
// everyone not present in german version..
security.SetAccessRule(
new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(everyone,
MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow));
MemoryMappedFile mmf;
if (read)
mmf = MemoryMappedFile.OpenExisting(FileName,
MemoryMappedFileRights.Read, //.ReadWriteExecute,
HandleInheritability.Inheritable);
else
mmf = MemoryMappedFile.CreateOrOpen(FileName,
this.length,
MemoryMappedFileAccess.ReadWrite,
MemoryMappedFileOptions.None,
security,
HandleInheritability.Inheritable);
file = mmf;
return mmf;
}
public Transfer ReadEntry()
{
try
{
var mf = this.GetMemoryMapFile(read: true);
byte[] arr = new byte[length];
int offset = 0;
using (var accessor = mf.CreateViewAccessor(0, length))
{
accessor.ReadArray(offset, arr, offset, length);
}
var str = System.Text.Encoding.UTF8.GetString(arr, 0, length);
return Serializer.DeserializeFromText<Transfer>(str);
}
catch (Exception)
{
return new Transfer();
}
}
public void WriteEntry(Transfer entry)
{
try
{
var mf = this.GetMemoryMapFile(read: false);
int offset = 0;
var str = Serializer.SerializeToText(entry);
byte[] arr = System.Text.Encoding.UTF8.GetBytes(str);
using (var accessor = mf.CreateViewAccessor(0, this.length))
{
accessor.WriteArray(offset, arr, offset, arr.Length);
}
}
catch { }
}
编辑: 查看答案,主要问题是 2 个进程是服务和用户应用程序,因此规则略有不同。
此外,我不确定我是真的需要 "complicated" GetMMF 版本还是像
这样的简单版本
private MemoryMappedFile GetMemoryMapFile()
{
var mmf = MemoryMappedFile.CreateOrOpen(FileName,
this.length);
return mmf;
}
我从来没有完全理解这个问题。我在服务应用程序和用户应用程序之间共享一个 MMF。这就是问题所在。
我想除了将文件命名为 "global\myfile" 而不是 "myfile".
外,我不需要做太多更改。
另请参阅 https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ebbc9cc3-03a4-4111-a157-fc5777929acb/shared-memory-between-a-service-and-a-user-app-in-windows-7?forum=windowssdk&prof=required 了解更多详细信息(虽然这是基于 C++ 的)。
我会看到将服务标签添加到原始问题中,只是为了让未来的读者更清楚。
内存映射文件有问题。
1) 每次我请求一个文件(同名),我似乎得到一个新文件。我写的字节在下次访问时不存在。我只是设法通过持久化对象来解决这个问题,我认为不应该需要它。
2) 至于进程间通信,我似乎也总是为我拥有的2个进程获得2个不同的mmf对象,至少我没有看到另一个进程的变化。
两个进程之间的文件名相同,并且在连续调用之间保持相同。
代码略有修改 http://www.abhisheksur.com/2012/02/inter-process-communication-using.html .
if 条件中的 "read" 参数及其背后的代码也没有任何改善。
MemoryMappedFile file = null;
private MemoryMappedFile GetMemoryMapFile(bool read)
{
if (file != null)
return file;
var security = new MemoryMappedFileSecurity();
var everyone = new System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.WorldSid, null);
//
// everyone not present in german version..
security.SetAccessRule(
new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(everyone,
MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow));
MemoryMappedFile mmf;
if (read)
mmf = MemoryMappedFile.OpenExisting(FileName,
MemoryMappedFileRights.Read, //.ReadWriteExecute,
HandleInheritability.Inheritable);
else
mmf = MemoryMappedFile.CreateOrOpen(FileName,
this.length,
MemoryMappedFileAccess.ReadWrite,
MemoryMappedFileOptions.None,
security,
HandleInheritability.Inheritable);
file = mmf;
return mmf;
}
public Transfer ReadEntry()
{
try
{
var mf = this.GetMemoryMapFile(read: true);
byte[] arr = new byte[length];
int offset = 0;
using (var accessor = mf.CreateViewAccessor(0, length))
{
accessor.ReadArray(offset, arr, offset, length);
}
var str = System.Text.Encoding.UTF8.GetString(arr, 0, length);
return Serializer.DeserializeFromText<Transfer>(str);
}
catch (Exception)
{
return new Transfer();
}
}
public void WriteEntry(Transfer entry)
{
try
{
var mf = this.GetMemoryMapFile(read: false);
int offset = 0;
var str = Serializer.SerializeToText(entry);
byte[] arr = System.Text.Encoding.UTF8.GetBytes(str);
using (var accessor = mf.CreateViewAccessor(0, this.length))
{
accessor.WriteArray(offset, arr, offset, arr.Length);
}
}
catch { }
}
编辑: 查看答案,主要问题是 2 个进程是服务和用户应用程序,因此规则略有不同。
此外,我不确定我是真的需要 "complicated" GetMMF 版本还是像
这样的简单版本 private MemoryMappedFile GetMemoryMapFile()
{
var mmf = MemoryMappedFile.CreateOrOpen(FileName,
this.length);
return mmf;
}
我从来没有完全理解这个问题。我在服务应用程序和用户应用程序之间共享一个 MMF。这就是问题所在。
我想除了将文件命名为 "global\myfile" 而不是 "myfile".
外,我不需要做太多更改。另请参阅 https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ebbc9cc3-03a4-4111-a157-fc5777929acb/shared-memory-between-a-service-and-a-user-app-in-windows-7?forum=windowssdk&prof=required 了解更多详细信息(虽然这是基于 C++ 的)。
我会看到将服务标签添加到原始问题中,只是为了让未来的读者更清楚。