問題
File.AppendAllText
是否管理來自多個作者的衝突?File.AppendAllText是否管理衝突(即多用戶併發)?
研究
我注意到MSDN documentation並沒有真正提供一個位置無論哪種方式,所以我決定我要反映的代碼,只是看看會發生什麼。下面是從File.AppendAllText
調用方法:
private static void InternalAppendAllText(string path, string contents, Encoding encoding)
{
using (StreamWriter streamWriter = new StreamWriter(path, true, encoding))
{
streamWriter.Write(contents);
}
}
,正如你可以看到它只是利用了StreamWriter
。所以,如果我們深入一點成,特別是它採用的構造,我們發現,它最終調用此構造函數:
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);
}
具有以下值:
path: the path to the file
append: the text to append
encoding: UTF8NoBOM
bufferSize: 1024
checkHost: true
,並進一步我們發現, base(null)
的實現並沒有做任何事情,只是將InternalFormatProvider
設置爲null
。因此,如果我們不斷挖掘我們發現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);
}
創建這些參數值的FileStream
:
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
的所以現在我們終於取得了一些進展,因爲我們要充分利用Windows API,這是問題真正開始的地方,因爲FileStream::ctor
調用名爲Init
的方法。這是一個相當長的方法,但我在一條線很感興趣:
this._handle = Win32Native.SafeCreateFile(text3,
dwDesiredAccess,
share,
secAttrs,
mode,
num,
IntPtr.Zero);
當然,它調用CreateFile
,其中參數值是:
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)
這樣,這將視窗做,如果我有兩個線程試圖同時訪問同一路徑上的該呼叫?它會打開文件並緩衝寫入,這樣兩個使用者都可以寫入文件嗎?或者我需要利用鎖定對象和lock
圍繞呼叫AppendAllText
?
現在,這是一個想法!讓**一名作者閱讀隊列**大大簡化了問題。在這樣的PROD中,我有不止一種場景,但其中一種是日誌記錄,您是否有一個方便使用'BlockingCollection'進行日誌記錄的例子?如果不是,不用擔心,我可以做到。 –
不要擔心我的朋友的例子,這是蛋糕。一個簡單的問題,但。你提到它可能是過度殺傷,除非它是用於記錄的東西。這是因爲類型本身的開銷(即在較低的事務情況下會導致性能問題)? –
@MichaelPerrenoud - 如果您使用它來進行日誌記錄,取決於多少,您可能更喜歡使用日誌框架,例如'Log4Net',它應該爲您處理多線程場景http://stackoverflow.com/questions/1519211/multithread -safe-logging – keyboardP