1

I have an issue with memorymappedfiles.

1) Each time I request a file (with the same name), I seem to get a new file. The bytes I wrote are not present on next access. I only managed to fix that by persisting the object, which I thought should not be needed.

2) As for inter process communication, I also always seem to get 2 different mmf objects for the 2 processes I have, at least I don't see the changes of the other process.

The FileName is both the same between the 2 processes and also it stays the same between successive calls.

The code is slightly modified off http://www.abhisheksur.com/2012/02/inter-process-communication-using.html .

The "read" parameter and the code behind it in the if condition also does not change anything for the better.

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 { }
}

Edit: see answer, the main problem was with the 2 processes being a service and a user app, so there are slightly different rules.

Also, I am not sure if I really need the "complicated" GetMMF version or just a simplre one like

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

        return mmf;
    }
Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104
  • 2
    From the docs at https://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile(v=vs.110).aspx : "Changes are automatically propagated to disk when the file is unmapped" - where do you unmap the file? The `WriteArray` method only writes to the in-memory copy. – peeebeee Jan 19 '18 at 14:41
  • Well, I thought the in-memory was shared? After all, I never give a "real" file path on disk. So the MemoryMappedFiles are based on shared memory. That was the assumption I got off several posts on the topic. – Andreas Reiff Jan 19 '18 at 14:47
  • Ah ok, I see the `using` now. – peeebeee Jan 19 '18 at 14:48
  • Thanks for all the good ideas! – Andreas Reiff Jan 20 '18 at 10:51

1 Answers1

0

I never fully understood the problem.. I am sharing an MMF between a service app and a user app. So that is the issue.

I guess I did not have to change much more than naming the file "global\myfile" rather than "myfile".

See also 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 for some more details (thoug this is C++ based).

I will see to add the service tag to original question, just to make it clearer for future readers.

Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104