【问题标题】:How to test concurrency scenarios in .NET?如何在 .NET 中测试并发场景?
【发布时间】:2014-08-18 10:58:57
【问题描述】:

我使用过并发,但我不知道有什么好的方法来测试它。

我想知道是否有任何方法可以“强制”任务以特定顺序执行以模拟测试用例。

例如:

  1. 客户端 #1 发出请求
  2. 服务器开始向客户端 #1 检索数据
  3. 客户端 #2 在服务器仍在响应客户端 #1 时发出另一个请求
  4. 断言>

我见过一些人使用自定义 TaskScheduler。有意义吗?

【问题讨论】:

  • 为什么不简单地依次等待每个请求?
  • 我看不到如何指定诸如“当第一个操作挂起时,开始另一个操作”之类的内容。
  • 做了一些谷歌搜索,基本上归结为多线程,启动和睡眠以强制并发。关于这个主题有整本书。
  • 在没有 await 的情况下调用 awaitable 方法将立即启动它,并在遇到 await 时继续下一次调用。您可以使用 Task.WaitAll(...) 使操作并行。
  • 您要查找的是Chess,这是微软的一个研究项目。

标签: c# .net testing asynchronous concurrency


【解决方案1】:

我也曾多次遇到过这个问题。最终,我创建了一个助手,可以启动一堆线程来执行并发操作。助手提供同步原语和日志记录机制。这是来自单元测试的代码片段:

[Test]
public void TwoCodeBlocksInParallelTest()
{
    // This static method runs the provided Action delegates in parallel using threads
    CTestHelper.Run(
        c =>
            {
                Thread.Sleep(1000); // Here should be the code to provide something 
                CTestHelper.AddSequenceStep("Provide"); // We record a sequence step for the expectations after the test
                CTestHelper.SetEvent();
            },
        c =>
            {
                CTestHelper.WaitEvent(); // We wait until we can consume what is provided
                CTestHelper.AddSequenceStep("Consume"); // We record a sequence step for the expectations after the test
            },
        TimeSpan.FromSeconds(10)); // This is a timeout parameter, if the threads are deadlocked or take too long, the threads are terminated and a timeout exception is thrown 

    // After Run() completes we can analyze if the recorded sequence steps are in the correct order
    Expect(CTestHelper.GetSequence(), Is.EqualTo(new[] { "Provide", "Consume" }));
}

它可以用来测试客户端/服务器或组件中的同步,或者只是运行一个超时的线程。我将在接下来的几周内继续改进这一点。这是项目页面: Concurrency Testing Helper

【讨论】:

    【解决方案2】:

    这应该不太难模拟使用任务:

    private async Task DoSomeAsyncOperation()
    {
        // This is just to simulate some work,
        // replace this with a usefull call to the server
        await Task.Delay(3000);
    }
    

    现在,让我们吃吧:

    public async Task TestServerLoad()
    {
       var firstTaskCall = DoSomeAsyncOperation();
    
       await Task.Delay(1000); // Lets assume it takes about a second to execute work agains't the server
       var secondCall = DoSomeAsyncOperation();
    
       await Task.WhenAll(firstTaskCall, secondCall); // Wait till both complete
    }
    

    【讨论】:

      【解决方案3】:

      这是并发中基本的生产者-消费者问题。如果您想测试这种情况,只需将 Thread.Sleep(100) 放入服务器,哪个部分响应消费者。这样,您的服务器在发送响应之前会有延迟。并且您可以简单地在循环中创建新线程来调用服务请求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-10
        • 1970-01-01
        相关资源
        最近更新 更多