MemoryMappedFiles:持久性和进程间通信

时间:2018-01-19 14:31:02

标签: c# windows-services ipc memory-mapped-files

我遇到了memorymappedfiles的问题。

1)每次我请求一个文件(同名),我似乎得到一个新文件。我写的字节在下次访问时不存在。我只是设法通过持久化对象来解决这个问题,我认为不应该这样做。

2)对于进程间通信,我似乎总是为我所拥有的2个进程获得2个不同的mmf对象,至少我没有看到其他进程的变化。

FileName在两个进程之间是相同的,并且在连续的调用之间保持不变。

代码稍稍修改为http://www.abhisheksur.com/2012/02/inter-process-communication-using.html

"阅读"参数及其在if条件下的代码也不会改变任何东西。

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);
    // https://stackoverflow.com/a/5398398/586754
    // 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个流程是服务和用户应用,因此规则略有不同。

另外,我不确定我是否真的需要&#34;复杂&#34; GetMMF版本或只是简单的

    private MemoryMappedFile GetMemoryMapFile()
    {
        var mmf = MemoryMappedFile.CreateOrOpen(FileName,
                          this.length);

        return mmf;
    }

1 个答案:

答案 0 :(得分:0)

我从未完全理解这个问题。我在服务应用和用户应用之间共享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 ++的。)

我会看到将服务标签添加到原始问题中,只是为了让未来读者更清楚。