0

My console application opens 100 threads which do exactly the same - sends some date to host in internal network. The host is very responsive, I have checked that it can handle much bigger number of requests in every second. The console application also is quite primitive and responsive (it doesn't use database or something) - it only sends requests to host. Increasing the number of threads doesn't improve the speed. It seems something is throttling the speed of communication the app with the host. Moreover I have run three instances of the same console application in the same time, and they have made 3x time more, so it seems the limitation is one the level of application.

I have already increased DefaultConnectionLimit but with no effect.

class Program
{
    static void Main(string[] args)
    {
        System.Net.ServicePointManager.DefaultConnectionLimit = 200;

        for (var i = 1; i <= 100; i++)
        {
            int threadId = i;
            Thread thread = new Thread(() =>
            {
                Testing(threadId);
            });
            thread.Start();
        }
    }

    private static void Testing(int threadId)
    {
        //just communicate with host
    }
}
Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
Barney
  • 154
  • 1
  • 3
  • 12
  • Do you want to wait for the response from server and then execute the next request? I believe you want to perform simultaneous calls which would need you to make asynchronous calls to the server with the threads. – praty May 28 '19 at 11:57
  • You haven't provided detail for "just communicate with host", but there is a reasonable chance that that provides an async version of the method. If so, you wouldn't even need to roll your own task around it, just keep track of the tasks it starts. There is no need for threads here. – Adam G May 28 '19 at 12:34

2 Answers2

1

Creation of a new Thread everytime is very expensive. You shouldn't create threads explicitly. Use task api instead to run this on threadpool:

var tasks = new Task[100];
for (var i = 0; i < 100; i++)
{
    int threadId = i;
    tasks[i] = Task.Run(() => Testing(threadId));
}
Task.WhenAll(tasks).GetAwaiter().GetResult();
mtkachenko
  • 5,389
  • 9
  • 38
  • 68
  • Its my understanding that Thread vs Threadpool would depend on what is being done in the Testing method. The post: https://stackoverflow.com/questions/230003/thread-vs-threadpool mentions that Threadpool is primarily beneficial if the thread would be short lived. If the thread will be long running, the thread creation is probably negligible. – Wiz May 28 '19 at 17:32
  • 1
    @Wiz General best practice: use Tasks instead of Threads. Threadpool is about `relatively short-lived operations` not just `short-lived`. If you want to create a new thread explicitly you should really understand why you need it. You should measure it. Real long operation is something like thread with `while(true)` inside to run some code periodically during entire application lifetime. Also read this one https://stackoverflow.com/questions/26921191/how-to-pass-longrunning-flag-specifically-to-task-run I like answer from Stephen Cleary – mtkachenko May 28 '19 at 18:13
1

The thing is that craeting more threads than you have cores in your processors is pointless.

For example you have 4 cores and create 100 threads: where do you expect 96 threads to run? They have to wait and decrease of performance is due to creating and managing unnecessary threads.

You should use ThreadPool, which will optimize number of threads created and scheduled to work.

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • Thanks for answer. But why running 3 instances of the same application in the same time makes the increase of speed 3 times? These instances run on the same machine and use the same cores. – Barney May 28 '19 at 12:28
  • @Barney Sorry, I don't get your question – Michał Turczyn May 28 '19 at 12:32
  • You are saying that limitation is that there aren't enough cores to run this 100 threads. But I have checked and run 3 instances of the same application, so in the same time there were running 300 threads. And these 3 instances have made in the same time, 3 times more requests to host. So the cores are capable to perform much more as one instance of application. – Barney May 28 '19 at 12:39
  • I could be wrong, but I think the number of cores would only affect it if all threads are running at 100% CPU usage for the entire life of the thread. If there is any sleep or wait for response from a server in the thread, it would allow the other threads to continue processing. I've seen many apps with more threads than cores and they perform better than if the threads were limited to the core count. – Wiz May 28 '19 at 15:41