锁(x){}在C#中超时了吗?(试图强制单元测试串行运行)

本文关键字:运行 单元测试 超时 中超 | 更新日期: 2023-09-27 18:20:37

我有一些C#单元测试必须串行运行,因为它们会清理整个数据库并设置指定的状态。同时这样做会导致不可预测的行为。出于这个原因,我试图在XML中将并行测试的数量设置为1,但它仍然进行并行测试。因此,我的下一个方法是使用[TestInitialize()][TestCleanup()]方法/扩展来强制进行串行处理。

这是我的代码:

    static Object exclusiveDbAccess = new Object();
    //Use TestInitialize to run code before running each test
    [TestInitialize()]
    public void MyTestInitialize()
    {
        lock (exclusiveDbAccess)
        {
            Monitor.Enter(exclusiveDbAccess);
        }
    }
    //
    //Use TestCleanup to run code after each test has run
    [TestCleanup()]
    public void MyTestCleanup()
    {
        lock (exclusiveDbAccess)
        {
            Monitor.Exit(exclusiveDbAccess);
        }
    }

这似乎在大多数情况下都有效,但我的效果(即使很少)看起来仍然有一些并行测试在运行。由于这种情况总是发生在计算机负载很大的时候,我想知道这是否不是由于"锁定()"超时(例如10或30秒后)造成的。例如,如果锁定()块在尝试获取锁定失败x秒后被跳过,这可能会导致这些问题。

所以我想请一些专家告诉我"锁定"语句的确切行为。请不要只是发布任何"猜测"。如果锁定()会超时,当然欢迎使用经验报告。。。

锁(x){}在C#中超时了吗?(试图强制单元测试串行运行)

这对我来说似乎是一个错误的用法。

lock(syncObject) { somecode }

基本上与相同

Monitor.Enter(syncObject);
try { somecode } 
finally { Monitor.Exit(syncObject); }

因此在同一对象上执行lockMonitor.Enter/Monitor.Exit似乎是不对的

这两个都不应该超时,除非您明确设置了一些超时(如Monitor.TryEnter(syncObject, timeout)

请参阅msdn+

它们不会超时,但您不应该使用lockMonitor.Enter()

你应该这样做:

static Object exclusiveDbAccess = new Object();
//Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
    Monitor.Enter(exclusiveDbAccess);
}
//
//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
    Monitor.Exit(exclusiveDbAccess);
}

形式的lock语句

lock (x) ...

是这样实现的:

System.Threading.Monitor.Enter(x);
try {
    ...
}
finally {
    System.Threading.Monitor.Exit(x);
}

(来自C#语言规范,第8.12节)