title: Does File.AppendAllText manage collisions (i.e. multi-user concurrency)?
body: <h1>Question</h1>
  <p>Does <code>File.AppendAllText</code> manage collisions from multiple writers?</p>
  <h1>Research</h1>
  <p>I noticed that the <a href="http://msdn.microsoft.com/en-us/library/ms143356.aspx" rel="noreferrer">MSDN documentation</a> doesn't really provide a position either way, so I decided I'd reflect the code and just see what it does. Below is the called method from <code>File.AppendAllText</code>:</p>
  <pre><code>private static void InternalAppendAllText(string path, string contents, Encoding encoding)
  {
      using (StreamWriter streamWriter = new StreamWriter(path, true, encoding))
      {
          streamWriter.Write(contents);
      }
  }
  </code></pre>
  <p>and as you can see it simply leverages a <code>StreamWriter</code>. So, if we dig a little deeper into that, specifically the constructor it uses, we find that it ultimately calls this constructor:</p>
  <pre><code>internal StreamWriter(string path, bool append, Encoding encoding, int bufferSize, bool checkHost) : base(null)
  {
      if (path == null)
      {
          throw new ArgumentNullException(&quot;path&quot;);
      }
      if (encoding == null)
      {
          throw new ArgumentNullException(&quot;encoding&quot;);
      }
      if (path.Length == 0)
      {
          throw new ArgumentException(Environment.GetResourceString(&quot;Argument_EmptyPath&quot;));
      }
      if (bufferSize &lt;= 0)
      {
          throw new ArgumentOutOfRangeException(&quot;bufferSize&quot;, Environment.GetResourceString(&quot;ArgumentOutOfRange_NeedPosNum&quot;));
      }
      Stream streamArg = StreamWriter.CreateFile(path, append, checkHost);
      this.Init(streamArg, encoding, bufferSize, false);
  }
  </code></pre>
  <p>with the following values:</p>
  <pre><code>path:        the path to the file
  append:      the text to append
  encoding:    UTF8NoBOM
  bufferSize:  1024
  checkHost:   true
  </code></pre>
  <p>and further we find that the <code>base(null)</code> implementation doesn't really do anything but set the <code>InternalFormatProvider</code> to <code>null</code>. So, if we keep digging we find that <code>CreateFile</code>:</p>
  <pre><code>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);
  }
  </code></pre>
  <p>creates a <code>FileStream</code> with these parameter values:</p>
  <pre><code>path:         the path to the file
  mode:         FileMode.Append
  access:       FileAccess.Write
  share:        FileShare.Read
  bufferSize:   4096
  options:      FileOptions.SequentialScan
  msgPath:      just the file name of the path provided
  bFromProxy:   false
  useLongPath:  false
  checkHost:    true
  </code></pre>
  <p>an so now we're finally getting somewhere because we're about to leverage the Windows API, and this is where the question really begins because that <code>FileStream::ctor</code> calls a method named <code>Init</code>. It's a pretty long method, but I'm really interested in one line:</p>
  <pre><code>this._handle = Win32Native.SafeCreateFile(text3,
      dwDesiredAccess,
      share,
      secAttrs,
      mode,
      num,
      IntPtr.Zero);
  </code></pre>
  <p>which of course calls <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx" rel="noreferrer"><code>CreateFile</code></a>, where the parameter values are:</p>
  <pre><code>text3:            the full path to the 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)
  </code></pre>
  <p>so, what would Windows do if I had two threads trying to access that call at the same time for the same path? Would it open the file and buffer the writes so that both consumers are allowed to write to the file? Or do I need to leverage a lock object and <code>lock</code> around the call to <code>AppendAllText</code>?</p>