[英]What is the minimum wait time to use ManualResetEventSlim instead of ManualResetEvent?
[英]What is the usage of ManualResetEvent or ManualResetEventSlim here?
我有一个测试,我想确保从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
不会通过我的测试?
Task.WhenAll()仅等待所有任务,直到运行完成。 它将对结果进行排序,使其与传递任务对象的顺序相匹配,但不会强制执行任何顺序,尽管所有Task总是在内部按其出现的顺序启动(请参阅源代码 )。 如果您需要固定的执行顺序,那么您必须亲自处理它,例如使用WaitHandle(如ManualRestEvent或Semaphore)或使用任务继续方法。
这意味着,如果您的任务都同样短暂地运行(例如在您的示例中),则它们的执行顺序相同,而执行顺序相同。 但是,如果您的任务在不同的时间执行,例如task1-> 2000 ms和task2-> 20 ms,则task2将比task1早完成。
或者使用您的示例,当task1花费比task2更长的时间才能调用sut.MyMethod()时 ,结果将是不同的。 现在,如果您需要task1在task2之前完成,则需要控制流程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.