c# - Does File.AppendAllText manage collisions (i.e. multi-user concurrency)? -


question

does file.appendalltext manage collisions multiple writers?

research

i noticed msdn documentation doesn't provide position either way, decided i'd reflect code , see does. below called method file.appendalltext:

private static void internalappendalltext(string path, string contents, encoding encoding) {     using (streamwriter streamwriter = new streamwriter(path, true, encoding))     {         streamwriter.write(contents);     } } 

and can see leverages streamwriter. so, if dig little deeper that, constructor uses, find calls constructor:

internal streamwriter(string path, bool append, encoding encoding, int buffersize, bool checkhost) : base(null) {     if (path == null)     {         throw new argumentnullexception("path");     }     if (encoding == null)     {         throw new argumentnullexception("encoding");     }     if (path.length == 0)     {         throw new argumentexception(environment.getresourcestring("argument_emptypath"));     }     if (buffersize <= 0)     {         throw new argumentoutofrangeexception("buffersize", environment.getresourcestring("argumentoutofrange_needposnum"));     }     stream streamarg = streamwriter.createfile(path, append, checkhost);     this.init(streamarg, encoding, buffersize, false); } 

with following values:

path:        path file append:      text append encoding:    utf8nobom buffersize:  1024 checkhost:   true 

and further find base(null) implementation doesn't set internalformatprovider null. so, if keep digging find createfile:

private static stream createfile(string path, bool append, bool checkhost) {     filemode mode = append ? filemode.append : filemode.create;     return new filestream(path, mode, fileaccess.write, fileshare.read, 4096, fileoptions.sequentialscan, path.getfilename(path), false, false, checkhost); } 

creates filestream these parameter values:

path:         path file mode:         filemode.append access:       fileaccess.write share:        fileshare.read buffersize:   4096 options:      fileoptions.sequentialscan msgpath:      file name of path provided bfromproxy:   false uselongpath:  false checkhost:    true 

an we're getting somewhere because we're leverage windows api, , question begins because filestream::ctor calls method named init. it's pretty long method, i'm interested in 1 line:

this._handle = win32native.safecreatefile(text3,     dwdesiredaccess,     share,     secattrs,     mode,     num,     intptr.zero); 

which of course calls createfile, parameter values are:

text3:            full path file dwdesiredaccess:  1073741824 share:            1 (file_share_read) secattrs:         null mode:             4 (open_always) num:              134217728 | 1048576 (file_flag_sequential_scan | file_flag_posix_semantics) 

so, windows if had 2 threads trying access call @ same time same path? open file , buffer writes both consumers allowed write file? or need leverage lock object , lock around call appendalltext?

the key method:

private static stream createfile(string path, bool append, bool checkhost) {     filemode mode = append ? filemode.append : filemode.create;     return new filestream(path, mode, fileaccess.write, fileshare.read, 4096, fileoptions.sequentialscan, path.getfilename(path), false, false, checkhost); } 

it's opening fileshare.read, meaning other threads or processes can open file reading, no other process/thread can open writing.

you wouldn't want allow multiple concurrent writers. consider writing 2 large buffers. it's end being interleaved.

so, yes ... if have multiple threads might appending file, need synchronize access, lock.

another option, depending on application, have consumer thread reads text queue , appends file. way, 1 thread has access file. other threads put messages on queue writer thread services. pretty easy blockingcollection, overkill unless you're writing file on continual basis (as in logging).


Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -