tox*_*erd 5 c# concurrency unit-testing
我有一个包含这样的异步调用的方法:
public void MyMethod() {
...
(new Action<string>(worker.DoWork)).BeginInvoke(myString, null, null);
...
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Unity 并且创建模拟对象不是问题,但是如何测试 DoWork 被调用而不必担心竞争条件?
一个先前的问题提供了解决方案,但在我看来,等待句柄是一个黑客(比赛条件仍然存在,尽管它应该是几乎不可能提高)。
编辑:好的,我想我可以以非常笼统的方式问这个问题,但似乎我必须进一步详细说明这个问题:
我想为上面提到的 MyMethod 创建一个测试,所以我做这样的事情:
[TestMethod]
public void TestMyMethod() {
...setup...
MockWorker worker = new MockWorker();
MyObject myObj = new MyObject(worker);
...assert preconditions...
myObj.MyMethod();
...assert postconditions...
}
Run Code Online (Sandbox Code Playgroud)
最简单的方法是创建一个 MockWorker(),它在调用 DoWork 时简单地设置一个标志,并在后置条件中测试该标志。这当然会导致竞争条件,即在 MockWorker 中设置标志之前检查后置条件。
更正确的方法(我可能最终会使用)是使用等待句柄:
class MockWorker : Worker {
public AutoResetEvent AutoResetEvent = new AutoResetEvent();
public override void DoWork(string arg) {
AutoResetEvent.Set();
}
}
Run Code Online (Sandbox Code Playgroud)
...并使用以下断言:
Assert.IsTrue(worker.AutoResetEvent.WaitOne(1000, false));
Run Code Online (Sandbox Code Playgroud)
这是使用类似信号量的方法,这很好……但理论上可能会发生以下情况:
我是否误解了 AutoResetEvent 的工作原理?是我太偏执了,还是有聪明的办法来解决这个问题?
等待句柄将是我要做的方式。AFAIK(我不确定)异步方法正在使用等待句柄来触发该方法。
我不确定为什么您认为会发生竞争条件,除非您在 WaitOne 调用上给出的时间异常短。我会在 waitone 上放 4-5 秒,这样你就可以确定它是否坏了,而且这不仅仅是一场比赛。
另外,不要忘记等待句柄是如何工作的,只要创建了等待句柄,就可以有以下执行顺序
即使正常执行是
要么工作正常,等待句柄可以在 Thread2 开始等待之前设置,一切都会为您处理。
| 归档时间: |
|
| 查看次数: |
4754 次 |
| 最近记录: |