Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 测试时,xUnit和登录在同一个文件上_C#_Unit Testing_Xunit - Fatal编程技术网

C# 测试时,xUnit和登录在同一个文件上

C# 测试时,xUnit和登录在同一个文件上,c#,unit-testing,xunit,C#,Unit Testing,Xunit,我刚刚更新到XUnit2.1。 我通过从不同程序集并行运行的大量测试来使用此方法,以特定名称登录到同一文件。 问题是我无法管理并发性(即使使用),每次运行测试时,不同的测试都会显示: 错误是: Message: System.IO.IOException : The process cannot access the file 'C:\LOGS\myFileName-20170510.txt' because it is being used by another process. 我的方法是

我刚刚更新到XUnit2.1。 我通过从不同程序集并行运行的大量测试来使用此方法,以特定名称登录到同一文件。 问题是我无法管理并发性(即使使用),每次运行测试时,不同的测试都会显示:

错误是:

Message: System.IO.IOException : The process cannot access the file 'C:\LOGS\myFileName-20170510.txt' because it is being used by another process.
我的方法是:

private static void WriteToLogFile(string fileName, string strMessage)
        {
            DateTime utcNow = DateTime.UtcNow;
            lock (fileName)
            {
                using (StreamWriter w = File.AppendText(fileName + utcNow.Year + utcNow.Month.ToString("00") + utcNow.Day.ToString("00") + ".txt"))
                {
                    w.WriteLine("{0};{1};{2}", DateTime.UtcNow, SecurityHelper.GetPrincipalName(), strMessage);
                    w.Flush();
                    w.Close();
                }
            }
        }
我甚至尝试过(但这没有帮助):

private static void WriteToLogFile(字符串文件名、字符串strMessage)
{
DateTime utcNow=DateTime.utcNow;
锁定(文件名)
{
使用(StreamWriter w=File.AppendText(fileName+utcNow.Year+utcNow.Month.ToString(“00”)+utcNow.Day.ToString(“00”)+“.txt”))
{
w、 WriteLine(“{0};{1};{2}”,DateTime.UtcNow,SecurityHelper.GetPrincipalName(),strMessage);
w、 冲洗();
w、 Close();
}
}
}
私有静态只读ConcurrentDictionary令牌=新ConcurrentDictionary();
私有静态对象GetToken(字符串文件名)
{
如果(!Tokens.ContainsKey(文件名))
TryAdd(文件名,新对象());
返回令牌[文件名];
}
这是因为xUnit的一些奇怪行为?
提前感谢。

以下行有问题:

lock (fileName)
不要将字符串和参数用作锁定对象。在您的情况下,尝试使用私有静态对象。见和。看起来是这样的:

private readonly object Locker = new object();

private static void WriteToLogFile(string fileName, string strMessage)
{
    DateTime utcNow = DateTime.UtcNow;
    lock (Locker)
    {
    ...
这解决了多个线程希望同时写入的潜在问题,但这不是真正的问题。看看这个。我不知道xunit测试运行程序是如何工作的,但是如果有多个进程同时写入,您将得到该异常。不要使用
File.AppendText
使用此选项(如stackoverflow问题的答案所示):

操作系统将允许多个进程访问同一文件

您可能仍然存在以下问题:内容可能很混乱,因为例如,两个进程可能希望在同一行写入,然后连续转储两个换行符。作为一种解决方法,您可以将进程ID附加到日志文件中


如果这太奇怪了,请考虑使用一个日志库来管理这种问题。

写日志文件的方法,是用在生产代码中还是在测试代码中?@ TeOLYNEDOFF!这无助于回答你的问题,但如果你想避免未来非常非常痛苦。。。使用记录器库,而不是滚动您自己的记录器。使用log4net或nlog。甚至System.Diagnostic.Trace也更好。请为了你自己。。。如果可能的话,考虑一下。每次有人使用File.AppendText(或类似的东西)作为日志记录机制时,小猫就会死去。是的。。。小猫也因为我死了。我只是不想再看到死猫了。到处都是死猫!他们在和我说话。他们想要我的灵魂。不。。。理智是很重要的。考虑它。储物柜应该是代码>私人只读静态对象< /代码>!?非常感谢你!最后,因为我的记录器需要在不同的文件上写入(哪个文件取决于日志类型),所以我使用了一个字典:
private static readonly ConcurrentDictionary LockDictionary=new ConcurrentDictionary{}其中LogType是一个枚举,但我认为它甚至可以是一个字符串。当我锁定时:
lock(LockDictionary[logType]){using(…)…}
谢谢!不客气。字符串可用于锁定,但不建议使用它(请参阅)。通常使用
对象
private readonly object Locker = new object();

private static void WriteToLogFile(string fileName, string strMessage)
{
    DateTime utcNow = DateTime.UtcNow;
    lock (Locker)
    {
    ...
using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.Read))
{
}