在多个线程中实例化非静态类时的对象引用错误

问题描述 投票:0回答:1

我正在使用C#和NUnit框架同时在单独的线程中执行多个测试。我想记录某些操作之间的时间,并为此创建了一个ActionTimeHelper类。

下面是类的代码以及使用类中方法的上下文

当我在并行机器人中运行两个测试时,调用Login方法然后只有一个测试完成,另一个测试抛出错误

(Message: System.NullReferenceException : Object reference not set to an instance of an object.
) at actionList.Add(new ActionTimeInfo()

我已将actionList设为ThreadStatic,以便在其自己的线程上运行的每个测试都有自己的副本,因此我无法弄清楚为什么会出现错误。

注意:如果我一次运行一个测试,一切正常

有人可以指导我这个。谢谢您的帮助。

已阅读一些文章Referencing a non static member with an instantiated objectReferencing an instantiated object in a static class (c#)但无法将我的具体问题联系起来

public static class ActionTimeHelper
{
private static readonly string _actionTimeLogFileName = "ActionTimeLog_" + string.Format("{0:yyyy_MM_dd_hhmmss}", DateTime.Now);
[ThreadStatic] private static FileStream _fileStream = null;
[ThreadStatic] private static StreamWriter _actionStreamWriter = null;
[ThreadStatic] private static JsonWriter _jsonWriter = null;
[ThreadStatic] private static List<ActionTimeInfo> actionList = new List<ActionTimeInfo>();

public static void CreateActionTimeLogFile(string logPath, string testName)
{
    string dir = logPath + testName + @"\";
    if (!Directory.Exists(dir))
    {
        Directory.CreateDirectory(dir);
    }
    _fileStream = File.Open(dir + _actionTimeLogFileName + ".json", FileMode.CreateNew);
    _actionStreamWriter = new StreamWriter(_fileStream);
    _jsonWriter = new JsonTextWriter(_actionStreamWriter);
    _jsonWriter.Formatting = Formatting.Indented;
    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(_jsonWriter, actionList);
    _fileStream.Flush();
    _actionStreamWriter.Flush();
    _jsonWriter.Flush();

}

public static void StartActionTime(string actionName)
{

    actionList.Add(new ActionTimeInfo()
    {
        TestName = TestContext.CurrentContext.Test.Name,
        ActionName = actionName,
        StartTime = DateTime.Now
    });
}

public static void EndActionTime(string actionName)
{
    ActionTimeInfo endAction = actionList.Find(actionInfo => actionInfo.ActionName.Equals(actionName));
    endAction.EndTime = DateTime.Now;
    endAction.ExecutionTime = endAction.EndTime.Subtract(endAction.StartTime);
}

}

public class ActionTimeInfo
{
public string TestName { get; set; }

public string ActionName { get; set; }

public DateTime StartTime { get; set; }

public DateTime EndTime { get; set; }

public TimeSpan ExecutionTime { get; set; }
}


public void Login(string username, string password)
{
    ActionTimeHelper.StartActionTime("Navigating to URL");
    ActionTimeHelper.EndActionTime("Navigating to URL");
    ActionTimeHelper.StartActionTime("Login Action");
    ActionTimeHelper.EndActionTime("Login Action");
    Thread.Sleep(30000);
}

[TearDown]
public void TestTearDown()
{
    ActionTimeHelper.CreateActionTimeLogFile(LogPath, TestContext.CurrentContext.Test.Name);
}

实际结果:空引用错误预期结果:无空引用错误

c# nunit threadstatic
1个回答
1
投票

“不要为标记有ThreadStaticAttribute的字段指定初始值,因为这样的初始化只在类构造函数执行时发生一次,因此只影响一个线程。如果未指定初始值,则可以依赖于将字段初始化为其默认值(如果它是值类型),如果它是引用类型则为null。

https://docs.microsoft.com/en-us/dotnet/api/system.threadstaticattribute?view=netframework-4.8

© www.soinside.com 2019 - 2024. All rights reserved.