MSpec:如何使静态变量线程安全

本文关键字:变量 线程 安全 静态 何使 MSpec | 更新日期: 2023-09-27 18:20:42

我正在为我的最新项目使用MSpec,总的来说,我对此非常满意。然而,当我的测试在paralel中运行时,我确实遇到了并发问题,我想知道是否有人遇到过这个问题,或者更好的是,有解决方案吗?

MSpec在很大程度上依赖于静态方法和变量来工作。

现在,当我在多个测试类使用的基类中定义静态变量,并且我在并行中运行测试时,它们共享相同的静态变量,从而相互干扰。

我正在使用NCrunch和Resharper作为我的测试运行程序,并且我在两者中都遇到了问题。

有人熟悉这个问题吗?

MSpec:如何使静态变量线程安全

首先,我建议阅读MSDN上的Thead安全指南。这将让您很好地了解如何以及为什么在C#中使方法线程安全。

以下规则概述了实现线程的设计指南:

  • 避免提供改变静态状态的静态方法。在常见的服务器场景中,静态状态在请求之间共享,这意味着多个线程可以同时执行该代码。这为线程错误打开了可能性。考虑使用一种设计模式,将数据封装到不在请求之间共享的实例中
  • 。。。添加锁来创建线程安全代码会降低性能,增加锁争用,并造成死锁错误发生的可能性
  • 请注意锁定部分中的方法调用。当类a中的静态方法调用类B中的静态法时,可能会导致死锁,反之亦然。如果A和B都同步它们的静态方法,这将导致死锁。您可能只有在线程压力很大的情况下才会发现这种死锁
  • 请注意lock语句(Visual Basic中的SyncLock)的问题。使用lock语句来解决所有线程问题是很诱人的。但是,System.Threading.Interlocked类对于必须是原子的更新更高级

一般来说,我更喜欢使用的方法(在可能的情况下)是使方法(静态或其他)不可变。要做到这一点,所有变量都应该是本地的(在堆栈上本地创建,或者作为参数传递给方法)。通过确保只使用局部变量,或者成员变量是不可变的,每个线程将在自己的隔间中操作,对变量的更改不会影响另一个线程。这是我在.NET仿真软件中广泛使用的一种方法,可以在C#中实现无锁、高性能的多线程。

或者,如果变量必须是成员变量,并且对它们的可变访问可能受到锁定关键字的保护。小心使用锁会导致上下文切换(速度减慢),并引入死锁情况的可能性。它也不保证线程安全,因为锁的使用必须防止您试图防止的特定场景。

为了进一步阅读,我建议查看这些描述C#中线程安全性和不变性的相关问题:

  • 设计线程安全类
  • 实现线程安全
  • 为什么不可变对象是线程安全的

致问候,

默认情况下,静态字段不是线程安全的。为了使它们线程安全,可以使用[ThreadStatic]属性对它们进行装饰。

有关详细信息,请参阅MSDN上的ThreadStaticAttribute类。