'How to simulate long running process in .NET API Controller Correctly

I am trying to create a unit test to simulate my API being called by many people at the same time.

I've got this code in my unit test:

            var tasks = new List<Task>();
            for (int i = 0; i < 10; i++)
            {
                var id = i; // must assign to new variable inside for loop
                var t = Task.Run(async () =>
                {
                    response = await Client.GetAsync("/api/test2?id=" + id);
                    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
                });
                tasks.Add(t);
            }

            await Task.WhenAll(tasks);

Then in my controller I am putting in a Thread.Sleep.
But when I do this, the total time for all tests to complete is 10 x the sleep time.

I expected all the calls to be made and to have ended up at the Thread.Sleep call at more or less the same time.

But it seems the API calls are actually made one after the other.

The reason I am testing the parallel API call is because I want to test a deadlock issue with my data repository when using SQLite which has only happened when more than 1 user uses my website at the same time.

And I have never been able to simulate this and I thought I'd create a unit test, but the code I have now seems to not be executing the calls in parallel.

My plan with the Thread.Sleep calls was to put a couple in the Controller method to make sure all requests end up between certain code blocks at the same time.

Do I need to set a a max number of parallel requests on the Web Server or something or am I doing something obviously wrong?

Thanks in advance.

Update 1: I forgot to mention I get the same results with await Task.Delay(1000); and many similar alternatives.

Not sure if it's clear but this is all running within a unit test using NUnit.
And the "Web Server" and Client is created like this:

            var builder = new WebHostBuilder().UseStartup<TStartup>();           
            Server = new TestServer(builder);
            Client = Server.CreateClient();


Solution 1:[1]

I found the problem with my test.
It was not the TestServer or the client code, it was the Database code.

In my controller I was starting an NHibernate Transaction, and that was blocking the requests because it would put a lock on the table being updated.

This is correct, so I had to change my code a bit to not automatically start a transaction. But rather leave that up to the calling code to manage.

Solution 2:[2]

You can use Task.Delay(time in milliseconds). Thread.Sleep will not release a thread and it can't process other tasks while waiting to result.

Solution 3:[3]

The HttpClient class in .NET has a limit of two concurrent requests to the same server by default, which I believe might be causing the issue in this case. Usually, this limit can be overridden by creating a new HttpClientHandler and using it as an argument in the constructor:

new HttpClient(new HttpClientHandler
            {
                MaxConnectionsPerServer = 100
            })

But because the clients are created using the TestServer method, that gets a little more complicated. You could try changing the ServicePointManager.DefaultConnectionLimit property like below, but I'm not sure if that will work with the TestServer:

System.Net.ServicePointManager.DefaultConnectionLimit = 100;

That being said, I believe using Unit Tests for doing load testing is not a good approach and recommend looking into tools specific for load testing.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Serhii
Solution 3 Jeremy Caney