-1

我有一些必须连续运行的 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);
        }
    }

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

所以我希望一些专家告诉我那个“锁定”语句的确切行为。请不要只是发布任何“猜测”。如果 lock() 已知超时,当然欢迎经验报告......

4

2 回答 2

2

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

lock(syncObject) { somecode }

基本上和

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

所以在同一个对象上做lockMonitor.Enter/似乎不正确Monitor.Exit

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

msdn +

于 2013-07-02T10:46:40.297 回答
1

他们不会超时 - 但你不应该使用lock and 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 节)

于 2013-07-02T10:38:57.400 回答