Многопоточное тестирование бизнес-логики на основе семафоров c в C# / MSTEST - PullRequest
0 голосов
/ 10 марта 2020

В моем C# / Net Core проекте у меня есть метод, подобный

 var MySemaphore = new SemaphoreSlim(1, 1);

 public async Task<RetrievalStatusReply> InitializeUpdate()
        {

            // This instruction lets routine quit if lock is taken by other thread
            if (!MySemaphore.Wait(0))
            {
                // if can not enter the lock
                 return;
            }

            try
            {
                // business logic
            }
            finally
            {
                MySemaphore.Release();
            }
        }

, и я хотел бы проверить его поведение, используя какую-то многопоточную настройку или тестовую служебную библиотеку в MsTest, например, похож на Java Concurrentunit .

Как я мог написать такой тест для C# / Net Core?

1 Ответ

0 голосов
/ 10 марта 2020

Тестирование многопоточного кода может быть довольно грязным. Мой предпочтительный подход заключается в использовании ManualResetEvents для управления порядком выполнения. Обычно для этого требуется, чтобы у вас был какой-то способ применить код для тестирования, введя тестовый код или каким-либо другим способом.

Так что-то подобное должно дать согласованный результат теста:

    SemaphoreSlim MySemaphore = new SemaphoreSlim(1, 1);
    public ManualResetEventSlim BusinessLogicReached= new ManualResetEventSlim(false);
    public ManualResetEventSlim BusinessLogicWaiting = new ManualResetEventSlim(false);
    public bool InitializeUpdate()
    {
        // This instruction lets routine quit if lock is taken by other thread
        if (!MySemaphore.Wait(0))
        {
            // if can not enter the lock
            return false;
        }

        try
        {
            BusinessLogicReached.Set();
            BusinessLogicWaiting.Wait();
            return true;
        }
        finally
        {
            MySemaphore.Release();
        }
    }

    [Test]
    public void RunTest()
    {
        var updateTask = Task.Run(InitializeUpdate);
        BusinessLogicReached.Wait();
        Assert.IsFalse(InitializeUpdate()); // Semaphore taken
        BusinessLogicWaiting.Set();
        updateTask.Wait();
        Assert.IsTrue(updateTask.Result);
        Assert.IsTrue(InitializeUpdate()); // Semaphore released
    }
* 1005 Тем не менее, эти виды тестов трудоемки в написании и обслуживании и не доказывают общей безопасности потоков, поэтому может быть более экономически эффективным сделать тщательный анализ кода многопоточного кода.
...