Increasing performance and accuracy in multithreaded loop
So your first question.


  no thread function call will be skipped.


You seem to be lost on what the WaitAll(Task[]) function does. This function is essentially a while loop that only exits when all threads it is called upon have finished executing. In this case, your program  will always execute all threads in your 'tasks' list. If you were to call something like WaitAll(Task[], Int32) instead, like: Task.WaitAll(tasks, 500); then your code would wait 500 milliseconds for your threads to join, and then continue on. It would give you an undesirable affect of not guaranteeing the execution of all threads. 


  Also is there any way to improve the threaded loop? ...I was hoping to find a way to get them in order.


You have to understand that threads do not guarantee execution in order of insertion, or when they were started. Imagine you have a 5 gallon bucket that is half filled with bouncy balls. Each ball has a number on it from [0, n], and was placed in the bucket in order from 0 -> n. Now, if we put a lid on the bucket, shake the bucket, pull the lid off, put a blind fold on and then try to pull out the balls in order of n - 0 we have a close idea of what happens when trying to get an ordered execution of threads.


Edit:

Due to the comments from @ErnieL I realized that there is another aspect of multithreading which needs to be addressed about scope. We are not talking about scope as in my object exists between braces, but rather the scope of who has control over my object.

The point was brought up about doing StackLoopPoints.Pop().ToString(). Prima facie this is an easy thing to do and results in the data that we want, but there is actually a tricky situation happening behind the scenes. We have to ask ourselves: What happens in the time span between when Pop() and ToString() being called?


   The answer is we do not know. The reason is because Pop() and ToString() are two separate instructions, which in multithreading allows for a context switch (a.k.a. change in thread being executed) to occur. Since there is no way to force a context switch to not occur*** we have to code against the situation of a context switch occurring, this is what @ErnieL's comments are saying.


We can actually improve DoStuffStack(int ctr) by protecting it a little bit.

Method 1

private static string DoStuffStack(int ctr)
{
    thread.Sleep(TimeSpan.FromSeconds(1d));
    // Pick which method you want to use. I realized the variable ctr is not being used, 
    // and wanted to give it a chance to do something.
    const int value = StackLoopPoints[ctr];  // This way we always grab the intended item.
    const int value = StackLoopPoints.Pop(); // This way we grab an item in the list as long as the list has items.
    return " " + value.ToString();
}


Method 2

There are better ways of dealing with thread safety than this, but this is a basic technique for dealing with safely removing an item from StackLoopPoints.

static int currentLock = 0;
private static string DoStuffStack(int ctr)
{
    while(currentLock != ctr)
    {
        thread.Sleep(TimeSpan.FromSeconds(1d));
        // This may fail to work correctly.
        // So please, do not break out of the loop in the if block.
        if(currentLock != -1)
        {
            currentLock = ctr;
        }
    }

    int value = StackLoopPoints.Pop(); // We can't return without clearing our variable.
    currentLock = -1; // We have the value we need, and no longer require the lock.

    return " " + value.ToString();
}




*** There are cases where you can force a context switch to not occur, but that is a conversation for another time.