2017-07-31 39 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()是什么吗?