2

After overcoming some other difficulties, I'm now stuck with this (probably simple) problem.

My goal:

  • Multiple instances of my application are running and performing operations (read & write) on the same file at the same time
  • Solution (what I want to do): use memory-mapped files to speed up the execution. When the app starts, it attempts to call CreateFromFile( ) (I understand that if the file has already been mapped by someone else, this will do nothing but return the "handle"), then proceeds to perform its work on the file.

The problem is that I'm getting an IOException (The file is being used by another process) upon an attempt to CreateFromFile( ) when another process has already done so and not disposed of MemoryMappedFile object. I could, theoretically, use mutexes and constantly dispose of the objects using the using statement, but that dumps the contents to disk, slowing the execution down again and defeating the purpose.

What are the possible solutions to my problem?

I could, theoretically, CreateOrOpen( ) a non-persisted file, then dump it to disk when needed, but I believe there's a better approach?

EDIT : I feel I didn't make myself clear. All instances of the app need to work on the file constantly, they open it and use it for the next 10, 20, 60 minutes without closing the file. Eventually all of them will be killed and that's when the OS steps in, flushing the map file to disk.

Example programs:

Program 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();
    }

Program 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();
}

I run both at the same time, let them hang waiting for the Console.Read(). Ideally, they should be able to access the file at the same time (i.e. both of them could open it after the other one has), but as stated above, I'm getting an IOException.

user4520
  • 3,401
  • 1
  • 27
  • 50
  • Show some code or it didn't happen! Do you use any `MemoryMappedFileSecurity` or `MemoryMappedFileAccess` when calling `CreateFromFile`? – bkdc Aug 01 '14 at 08:52
  • You will most likely need mutexes or something like that anyway in order to coordinate ops between processes. Frequent calls to open/close (`using` statements) will degrade your performance - as long as you make sure that things are handled properly (fix your issue with not properly disposing objects) you should be able to keep that file open for long periods without issues. – bkdc Aug 01 '14 at 08:56
  • Can you provide a minimal example which reproduces the problem? – ChrisWue Aug 01 '14 at 09:46
  • @bkdc No, I do not use these parameters. I've taken a look at http://msdn.microsoft.com/en-us/library/dd267557.aspx and found nothing suggesting they would fix my issue. I've edited my answer and added an example code snippet. – user4520 Aug 01 '14 at 15:44
  • Until I get the time to run some test you can try running both apps and use Process Monitor to see why the 2nd app can't open the file (filter events to include only the two apps and only File System events) - the logs should give you the reason why the file is locked. Or try Process Explorer to see which apps hold any handles to that file. – bkdc Aug 01 '14 at 15:55

0 Answers0