我正在将 MSpec 用于我的最新项目,总的来说我对它非常满意。但是,当我的测试并行运行时,我确实遇到了并发问题,我想知道是否有人遇到过这个问题,或者更好的是,有解决方案吗?
MSpec 严重依赖静态方法和变量来工作。
现在,当我在基类中定义由多个测试类使用的静态变量,并且并行运行测试时,它们共享相同的静态变量,从而相互干扰。
我使用 NCrunch 和 Resharper 作为我的测试运行程序,并且我在两者中都遇到了问题。
有人熟悉这个问题吗?
首先,我建议阅读MSDN 上的 Head 安全指南 http://msdn.microsoft.com/en-us/library/f857xew0%28v=vs.71%29.aspx。这将使您很好地了解如何以及为何在 C# 中使方法线程安全。
以下规则概述了实现线程的设计指南:
- 避免提供改变静态状态的静态方法。在常见的服务器场景中,静态状态在请求之间共享,这意味着多个线程可以同时执行该代码。这带来了线程错误的可能性。考虑使用一种设计模式,将数据封装到不在请求之间共享的实例中。
- ...添加锁来创建线程安全代码会降低性能,增加锁争用,并可能出现死锁错误
- 请注意锁定部分中的方法调用。当类 A 中的静态方法调用类 B 中的静态方法时,可能会导致死锁,反之亦然。如果A和B都同步它们的静态方法,这将导致死锁。您可能只有在线程压力很大的情况下才会发现这种死锁。
- 请注意 lock 语句(Visual Basic 中的 SyncLock)的问题。使用lock语句来解决所有线程问题是很诱人的。然而,System.Threading.Interlocked 类对于必须是原子的更新来说是优越的......
一般而言,我更喜欢使用的方法(如果可能)是创建一个方法(静态或其他)不可变的 http://en.wikipedia.org/wiki/Immutable_object。为此,所有变量都应该是本地变量(在堆栈上本地创建,或作为参数传递给方法)。通过确保仅使用局部变量或成员变量是不可变的,每个线程将在自己的隔间中操作,并且对变量的更改不会影响另一个线程。这是我在 .NET 模拟软件中广泛使用的一种方法,可以在 C# 中实现无锁,从而实现高性能多线程。
或者,如果变量必须是成员变量,并且对它们的可变访问可以由 lock 关键字保护。小心使用锁会导致上下文切换(减慢速度)并引入死锁情况的可能性。它也不能保证线程安全,因为锁的使用必须防止您试图阻止的特定情况。
为了进一步阅读,我建议查看这些描述 C# 中线程安全性和不变性的相关问题:
-
设计线程安全类 https://stackoverflow.com/questions/3128717/designing-a-thread-safe-class
-
实现线程安全 https://stackoverflow.com/questions/564319/achieving-thread-safety
-
为什么不可变对象是线程安全的 https://stackoverflow.com/questions/3595114/why-are-immutable-objects-thread-safe
此致,
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)