Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Tasks slows down

The code:

static void DoIt(string name)
{
    Console.WriteLine("Hello {0} | {1}", name, Thread.CurrentThread.ManagedThreadID);
    Thread.Sleep(5000);
    Console.WriteLine("Bye {0} | {1}", name, Thread.CurrentThread.ManagedThreadID);
}

static void Main()
{
    Task.Factory.StartNew(() => DoIt("One"));
    Task.Factory.StartNew(() => DoIt("Two"));
    Task.Factory.StartNew(() => DoIt("Three"));
    Task.Factory.StartNew(() => DoIt("Four"));
    Task.Factory.StartNew(() => DoIt("Five"));
    Task.Factory.StartNew(() => DoIt("Six"));
    Task.Factory.StartNew(() => DoIt("Seven"));
    Task.Factory.StartNew(() => DoIt("Eight"));
    Task.Factory.StartNew(() => DoIt("Nine"));
    Task.Factory.StartNew(() => DoIt("Ten"));

    Console.ReadKey();
}

How come that it can fine start the first 3 Tasks immediately, but then it takes 5-10sec for Task 4 to start, and after Task 4 have started, then it takes 5-10sec before Task 5 starts and so on. Is it the GC thats doing something? Could someone please clarify whats happening?

like image 332
ebb Avatar asked Sep 12 '11 20:09

ebb


People also ask

Why multitasking is not efficient?

Multitasking reduces your efficiency and performance because your brain can only focus on one thing at a time. When you try to do two things at once, your brain lacks the capacity to perform both tasks successfully. Research also shows that, in addition to slowing you down, multitasking lowers your IQ.

What happens to your brain when you multitask?

When the brain tries to do two things at once, it divides and conquers, dedicating one-half of our gray matter to each task, new research shows. But forget about adding another mentally taxing task: The work also reveals that the brain can't effectively handle more than two complex, related activities at once.

How can multitasking be harmful?

Trying to multitask produces changes in the brain that can cause depression, anxiety and actually decrease productivity. You read that correctly– decrease productivity. In short, multitasking is bad for your overall mental health. Fortunately, you can train your brain to be more effective at focused serial unitasking.


1 Answers

How come that it can fine start the first 3 Tasks immediately, but then it takes 5-10sec for Task 4 to start, and after Task 4 have started, then it takes 5-10sec before Task 5 starts and so on. Is it the GC thats doing something? Could someone please clarify whats happening?

By default, the first time you run this, the ThreadPool is allocated using the minimum number of worker threads. After the first 4 tasks are scheduled, the threadpool will "ramp up" to handle more over time, which is why you see the delay.

On my system (which has 8 cores), the first 8 are instantanteous, then the next two start up one second later.

In your case, if you run your test two times, the second time, the threads will all start up immediately. This is because, after the first run, the ThreadPool should have enough workers to schedule this right away.

Try the following to see this behavior in action. If you leave the SetMinThreads call in place, these will all schedule immediately. If you comment it out, you'll see that, the first time, it takes a while, but the second time through (provided you wait for the threads to complete), the threads will run immediately.

static void DoIt(string name)
{
    Console.WriteLine("Hello {0} | {1} - {2}", name, Thread.CurrentThread.ManagedThreadId, DateTime.Now);
    Thread.Sleep(5000);
    Console.WriteLine("Bye {0} | {1} - {2}", name, Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}

static void Main()
{
    int workerThreads, complete;
    ThreadPool.GetMinThreads(out workerThreads, out complete);

    Console.WriteLine(workerThreads);

    // Comment out this line to see the difference...
    // WIth this commented out, the second iteration will be immediate
    ThreadPool.SetMinThreads(100, complete);

    Action run = () =>
        {
            for (int i = 0; i < 20; ++i)
            {
                int tmp = i;
                Task.Factory.StartNew(() => DoIt(tmp.ToString()));
            }
        };

    run();
    Console.WriteLine("Press a key to run again...");
    Console.ReadKey();

    run();

    Console.WriteLine("Press a key to exit...");
    Console.ReadKey();
}

Note that this behavior actually has little to do with the TPL as a whole - it's more the default TaskScheduler used which just passes off the tasks to the ThreadPool. If you were to set these threads up with the LongRunning hint in your StartNew() call, for example, they'd all start immediately (since the default scheduler will setup a new, dedicated thread and execute it immediately).

like image 121
Reed Copsey Avatar answered Oct 09 '22 16:10

Reed Copsey