锁定(x){}是否超时C#? (试图强制单元测试以串行方式运行)

时间:2013-07-02 10:30:13

标签: c# locking

我有一些必须连续运行的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秒失败后将跳过lock()块,则可能会导致这些问题。

所以我想请一位专家告诉我“锁定”声明的确切行为。请不要发布任何“猜测”。如果知道lock()超时体验报告当然是受欢迎的......

2 个答案:

答案 0 :(得分:2)

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

lock(syncObject) { somecode }

基本上与

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

所以在同一个对象上执行lockMonitor.Enter / Monitor.Exit似乎不对

除非您明确设置了一些超时(如Monitor.TryEnter(syncObject, timeout)

,否则这些都不会超时

请参阅msdn +

答案 1 :(得分:1)

他们没有超时 - 但您不应该使用lock Monitor.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节)