【发布时间】:2018-05-19 19:19:06
【问题描述】:
我有一个测试,我想确保从async 方法中获得每个线程的隔离结果。我的测试如下所示:
public async Task MyMethod_Concurrency_ReturnsIsolatedResultPerThread()
{
int expectedResult = 20;
var theMock = new Mock<IService>();
theMock.Setup(m => m.GetResult(It.IsAny<int>()))
.Callback(() => Thread.Sleep(10))
.Returns<int>(t => Task.FromResult(expectedResult));
var sut = new MyClass(30, theMock.Object);
var rs1 = new ManualResetEventSlim();
var rs2 = new ManualResetEventSlim();
var task1 = Task.Run(async () =>
{
expectedResult = 40;
await sut.MyMethod();
rs2.Set();
rs1.Wait();
Assert.AreEqual(expectedResult, sut.Result);
});
var task2 = Task.Run(async () =>
{
rs2.Wait();
expectedResult = 45;
await sut.MyMethod();
Assert.AreEqual(expectedResult, sut.Result);
rs1.Set();
});
var task3 = Task.Run(() => Assert.AreEqual(0, sut.Amount));
await Task.WhenAll(task1, task2, task3);
}
测试工作正常并成功通过。但是,如果不使用ManualResetEventSlim,它也可以按预期工作。所以我的问题是这个例子中ManualResetEventSlim 的用法是什么?我真的对此感到困惑?谁能解释在我的测试中使用ManualResetEventSlim 或不使用它有什么区别?我该怎么做才能不使用ManualResetEvents就无法通过我的测试??
【问题讨论】:
-
hrm 让我们看看文档是怎么说的 msdn.microsoft.com/en-us/library/… 提供了一个精简版的 ManualResetEvent。嗯,让我们看看msdn.microsoft.com/en-us/library/… 是什么意思通知一个或多个等待线程发生了事件。嗯,如果它仍然不清楚,让我们看看代码是如何使用断点工作的 msdn.microsoft.com/en-us/library/5557y8b4.aspx
-
@TheGeneral 正如我所说,我的问题是:为什么我的测试通过了,即使没有使用
ManualResetEventSlim。我已经阅读了您已经提到的所有链接,但是在这个测试中我对ManualResetEventSlim感到困惑?另外我不知道为什么断点没有命中我的测试! -
那些 ManualResetEvents 在那里强制方法运行的顺序 - 虽然 - 我不知道为什么不简单地通过编写类似的东西来强制执行顺序:“await sut.MyMethod(); Assert. AreEqual(40, sut.Result); 等待 sut.MyMethod(); Assert.AreEqual(45, sut.Result);"您的测试在没有 ManualResetEvents 的情况下通过的原因是“巧合”
-
@johannes.colmsee 你能给我举个例子说明我该怎么做,这样我的测试就不会在没有
ManualResetEvents的情况下通过吗??
标签: c# multithreading unit-testing asynchronous async-await