.net - Is using of MemoryMappedFile instance, opened by MemoryMappedFile.OpenExisting method threadsafe? -


in wcf service need provide functionality of files downloading supporting of range http header chunked downloading. first call getfile method of service creates new memorymappedfile instance file on disk. let's assume in time when mmf created first request , request still processing, second call getfile method of service opening existing mmf , returning streamed response client. happens if mmf disposed (and source file closed on memorymappedfile disposing) thread create it? should second call read content opened viewstream or no?

i had wrote small test , seems till memorymappedfile opened openexisting method, it's lifetime extended , source file keeps opened. true, or missed pitfall? can't find documentation such case in msdn.

update: added additional thread.sleep call after existing mmf opened before obtaining mapview of file simulate threads race

private static readonly string mapname = "foo"; private static readonly string filename = @"some big file";  static void main(string[] args) {     var t1 = task.factory.startnew(openmemorymappedfile);     var t2 = task.factory.startnew(readmemorymappedfile);      task.waitall(t1, t2); }  private static void openmemorymappedfile() {     var stream = file.openread(filename);     using (var mmf = memorymappedfile.createfromfile(stream, mapname, 0, memorymappedfileaccess.read, null, handleinheritability.none, false))     {         console.writeline("memory mapped file created");         thread.sleep(1000); // timeout thread open existing mmf     }      console.writeline("memory mapped file disposed"); }  private static void readmemorymappedfile() {     thread.sleep(100); //wait till mmf created     var buffer = new byte[1024 * 1024]; //1mb chunk     long totallength = 0;     using (var f = file.openread(filename))     {         totallength = f.length;     }      using (var mmf = memorymappedfile.openexisting(mapname, memorymappedfilerights.read))     {         console.writeline("existing mmf opened successfully");         thread.sleep(2000); //simulate threads race          using (var viewstream = mmf.createviewstream(0, 0, memorymappedfileaccess.read))         {              console.writeline("view of file mapped successfully");             file.delete(path.getfilename(filename));               using (var filestream = file.open(path.getfilename(filename), filemode.createnew, fileaccess.write))             using (var writer = new binarywriter(filestream))             {                 int readbytes;                                 {                     readbytes = viewstream.read(buffer, 0, buffer.length);                     writer.write(buffer, 0, readbytes);                      console.write("{0:p}% of target file saved\r", filestream.length / (float)totallength);                     thread.sleep(10); //simulate network latency                  } while (readbytes > 0);                 console.writeline();                 console.writeline("file saved successfully");             }         }     } } 

an open view not pulled away under reading if other file handle disposed or file deleted. view stays valid until close explicitly. same goes file handles (you can delete file while handles still open , working - little known fact).

suppose closed if different file handle closed. code reading start generating access violations @ random points during execution. unsound design.

btw, threading timing-based , therefore broken. think trying create repro case can executed.


Comments

Popular posts from this blog

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -

java - JavaFX 2 slider labelFormatter not being used -