Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible always to force a new thread with Task?

I am trying to create a new thread each time Task.Factory.StartNew is called. The question is how to run the code bellow without throwing the exception:

static void Main(string[] args)
{
    int firstThreadId = 0;

    Task.Factory.StartNew(() => firstThreadId = Thread.CurrentThread.ManagedThreadId);

    for (int i = 0; i < 100; i++)
    {
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Thread.Sleep(1000);
                if (firstThreadId == Thread.CurrentThread.ManagedThreadId)
                    throw new Exception("The first thread is reused.");
            }
        });
    }
    Console.Read();
}

EDIT: the new code if you comment the first for statement there is no problem. But if you have it, WOW, the message "Thread reused" is written to the console. Can you explain that because I am really confused.

static void Main(string[] args)
{
    ConcurrentDictionary<int, int> startedThreads = new ConcurrentDictionary<int, int>();

    for (int i = 0; i < 10; i++)
    {
        Task.Factory.StartNew(() =>
        {
            Task.Factory.StartNew(() =>
            {
                startedThreads.AddOrUpdate(Thread.CurrentThread.ManagedThreadId,
                    Thread.CurrentThread.ManagedThreadId, (a, b) => b);
            }, TaskCreationOptions.LongRunning);

            for (int j = 0; j < 100; j++)
            {
                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        Thread.Sleep(10);
                        if (startedThreads.ContainsKey(
                            Thread.CurrentThread.ManagedThreadId))
                                Console.WriteLine("Thread reused");
                    }
                }, TaskCreationOptions.LongRunning);
            }
        });
    }

    Console.Read();
}
like image 817
mynkow Avatar asked Nov 26 '12 18:11

mynkow


2 Answers

If you specify TaskCreationOptions.LongRunning when starting the task, that provides a hint to the scheduler, which the default scheduler takes as an indicator to create a new thread for the task.

It's only a hint - I'm not sure I'd rely on it... but I haven't seen any counterexamples using the default scheduler.

like image 120
Jon Skeet Avatar answered Oct 13 '22 10:10

Jon Skeet


Adding to Jon Skeet's answer, if you want to guarantee that a new thread is created every time, you can write your own TaskScheduler that creates a new thread.

like image 33
SLaks Avatar answered Oct 13 '22 10:10

SLaks