1

To understand how to start multiple threads calling the same method, I want to use the following logic:

  • Create an array of threads
  • Initialize the Threads using a lambda expression
  • Start the threads.

The routine works if I use the Join function or if I start threads directly like this:

new Thread(EnterSemaphore).Start(i);

What I can see from the result is that the routine I am using is not working. Not all threads are displayed and I even see a thread with index number 6. I would like to understand why starting an array of threads like this fails.

class SemaphoreLock
{

    #region Fields
    // SemaphoreSlim _sem heeft de capaciteit voor 3 elementen 
    static SemaphoreSlim _sem = new SemaphoreSlim(3); // Capacity of 3

    public readonly object StartLocker = new object();

    #endregion

    #region Constructor
    // 
    public SemaphoreLock()
    {
        Thread[] testStart = new Thread[10];

        for (int i = 1; i <= 5; i++)
        {

            // If enabled, this works
            // new Thread(EnterSemaphore).Start(i);

            // This is not working.
            testStart[i] = new Thread(() => EnterSemaphore(i));
            lock (StartLocker) testStart[i].Start();

            // Adding a join here works, every thread is started as a single thread
            //testStart[i].Join();
        }

    }
    #endregion


    #region Methods
    static void EnterSemaphore(object id)
    {
        Console.WriteLine(id + " wants to enter");

        // Block the current thread until it can enter the Semaphore
        _sem.Wait();

        Console.WriteLine(id + " is in!");
        Thread.Sleep(1000 * (int)id);
        Console.WriteLine(id + " is leaving");
        _sem.Release();

        if (_sem.CurrentCount == 3)
        {

            Console.WriteLine("Done...");
        }
    }

       #endregion

}
Wouter
  • 29
  • 2
  • It's not the starting, but the finishing, one assumes. We have to assume, because you didn't provide a [mcve]. But it seems very likely that the code you posted is found in a simple console program that calls the constructor and then just exits. The console window disappears and then you don't get to see what your threads are doing. If you think that's not the answer, post a new question, but this time provide all the details. – Peter Duniho Jan 03 '18 at 09:10

1 Answers1

1

Your code works fine. With the use of thread Join you are just been able to see the different threads, since Thread.Join:

Blocks the calling thread until the thread represented by this instance terminates, while continuing to perform standard COM and SendMessage pumping.

As another example you could also use a Thread.Sleep() for viewing a similar behavior:

        testStart[i] = new Thread(() => EnterSemaphore(i));
        lock (StartLocker) testStart[i].Start();
        Thread.Sleep(100);

Even better , for witnessing the behavior use a ReadLine() in the end of for loop:

 for (int i = 1; i <= 5; i++)
 {      
   testStart[i] = new Thread(() => EnterSemaphore(i));
   lock (StartLocker) testStart[i].Start();
 }
 Console.ReadLine();
apomene
  • 14,282
  • 9
  • 46
  • 72