5

In C# 4.0, MemoryMappedFile has several factory methods: CreateFromFile, CreateNew, CreateOrOpen, or OpenExisting. I need to open the MemoryMappedFile if it exists, and if not, create it from a file. My code to open the memory map looks like this:

try
{
    map = MemoryMappedFile.OpenExisting(
        MapName,
        MemoryMappedFileRights.ReadWrite
        | MemoryMappedFileRights.Delete);
}
catch (FileNotFoundException)
{
    try
    {
        stream = new FileStream(
            FileName,
            FileMode.OpenOrCreate,
            FileAccess.ReadWrite,
            FileShare.Read | FileShare.Delete);
        map = MemoryMappedFile.CreateFromFile(
            stream, MapName, length + 16,
            MemoryMappedFileAccess.ReadWrite,
            null,
            HandleInheritability.None,
            false);
    }
    catch
    {
        if (stream != null)
            stream.Dispose();
        stream = null;
    }
}

It pretty much works the way I want it to, but it ends up throwing an exception on OpenExisting way too often. Is there a way to check whether the MemoryMappedFile actually exists before I try to do the OpenExisting call? Or do I have to deal with the exception every single time?

Also, is there a way to find out if the current handle is the last one to have the MemoryMappedFile open, to determine if the file will be closed when the current handle is disposed?

Krizz
  • 11,362
  • 1
  • 30
  • 43
Bryce Wagner
  • 2,640
  • 1
  • 26
  • 43
  • I don't get your question. What do you mean by "but it ends up throwing an exception on OpenExisting way too often"? – Krizz Feb 23 '12 at 22:31
  • 1
    If I try CreateFromFile first, it throws an exception if it's already open, if I try OpenExisting first, it throws an exception if it's not open. I want to completely avoid those exceptions if possible by checking whether it exists. I only want to deal with exceptions in truly exceptional circumstances, not every single time it hits that line of code. – Bryce Wagner Feb 23 '12 at 23:12
  • 1
    This isn't a real problem, you need to work on step #2 to make the MMF actually usable. That requires at least one named mutex to control what process can write to the mapped memory. One of those processes has to be the boss, the arbiter if you will. It needs to start first. – Hans Passant Feb 24 '12 at 00:59
  • The code is simplified, I actually have a mutex around the whole thing. Hmm, so maybe I should be taking advantage of the "createdNew" out parameter on the mutex. – Bryce Wagner Feb 24 '12 at 16:01

2 Answers2

0

You can use MemoryMappedFile.CreateOrOpen:

map = MemoryMappedFile.CreateOrOpen(
                MapName, length + 16,
                MemoryMappedFileAccess.ReadWrite, 
                MemoryMappedFileOptions.None, null, HandleInheritability.None);
Raj Ranjhan
  • 3,869
  • 2
  • 19
  • 29
  • 1
    The problem is, that just creates a memory-only map, it doesn't allow mapping to a filesystem file. Is there some way to hook it to a file after it has been opened? – Bryce Wagner Feb 24 '12 at 14:42
0

See Han Passant's comment under the original question for accepted answer. Since I can't mark it as accepted, I'll just refer to it here and mark this as accepted.

Bryce Wagner
  • 2,640
  • 1
  • 26
  • 43