2017-07-31 15 views
0

我有一個小型的記錄器類,它只包含一些靜態幫助器方法,可以方便地寫入日誌文件。我想測試它是多麼強大,所以我試圖一次100次異步運行它。異步寫入文件會導致不正確的行數和不正確的內容

[TestMethod] 
public void Diagnostics_AsyncWritePass() 
{ 
    int linesToWrite = 100; 
    String logMsg = "Async test log "; 
    List<Task> asyncTaskList = new List<Task>(); 

    for (int i = 0; i < linesToWrite; i++) 
    { 
     Task task = new Task(() => Logger.Info(logMsg + i)); 
     asyncTaskList.Add(task); 
     task.Start(); 
    } 

    Task.WaitAll(asyncTaskList.ToArray()); 

    List<String> lines = GetLastLogLines(linesToWrite); 

    foreach (String line in lines) 
    { 
     Assert.IsTrue(line.Contains(logMsg)); 
    } 
} 

的實際記錄(該Logger.Info方法內部)使用進行:

File.AppendAllText(LogPath, logMsg + Environment.NewLine); 

GetLastLogLines方法是:

private List<String> GetLastLogLines(int numLines) 
{ 
    List<String> lines = File.ReadLines(Logger.LogPath) 
     .Reverse() 
     .Take(numLines) 
     .ToList(); 
    return lines; 
} 

不過,我有這個兩個問題。

  • 第一個是它不是寫100行,它被寫入周圍90.
  • 第二個是,每行是Async test log 100 - 數量不增加的每一行。我猜測i計數器是通過引用傳遞的,而不是通過值。

爲什麼會出現這些問題?

編輯: 行發行的數量不正確被取代的GetLastLogLines內容解決。以前,它使用的是File.ReadLines,然後使用LINQ僅佔用x行。相反,我使用了this answer,它返回了正確的行數。

回答

0

當lambda表達式捕獲迭代變量時,第二個問題是標準問題。

進行以下更改。

for (int i = 0; i < linesToWrite; i++) 
{ 
    var t = i; 
    Task task = new Task(() => Logger.Info(logMsg + t)); 
    asyncTaskList.Add(task); 
    task.Start(); 
} 

你能告訴我們GetLastLogLines()是什麼嗎?