簡體   English   中英

這里的ManualResetEvent或ManualResetEventSlim有什么用?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM