I've tried this...
public ArrayList GetAllObjectAttributes()
    {
        List<Task> taskList = new List<Task>();
        ArrayList allObjectAttributes = new ArrayList();
        taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder));}));
        taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)); }));
        taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)); }));
        taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)); }));
        Task.WaitAll(taskList.ToArray());
        return allObjectAttributes;
    }
and this...
public ArrayList GetAllObjectAttributes()
    {
        Thread[] threads = new Thread[4];
        ArrayList allObjectAttributes = new ArrayList();
        threads[0] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder)));
        threads[1] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)));
        threads[2] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)));
        threads[3] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)));
        foreach(Thread thread in threads)
        {
            thread.Start();
            thread.Join();
        }
        return allObjectAttributes;
    }
and this too...
public ArrayList GetAllObjectAttributes()
    {
        Thread[] threads = new Thread[4];
        ArrayList allObjectAttributes = new ArrayList();
        threads[0] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder)));
        threads[1] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)));
        threads[2] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)));
        threads[3] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)));
        foreach(Thread thread in threads)
        {
            thread.Start();
        }
        while(threads[0].IsAlive || threads[1].IsAlive || threads[2].IsAlive || threads[3].IsAlive)
        {
            Thread.Sleep(500);
        }
        return allObjectAttributes;
    }
I also tried Spawn Multiple Threads for work then wait until all finished
I still get a null in one of the arraylist items in allObjectAttributes.
However, when I do
public ArrayList GetAllObjectAttributes()
    {
        ArrayList allObjectAttributes = new ArrayList();
        allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder)));
        allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)));
        allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)));
        allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)));
        return allObjectAttributes;
    }
I never get a null item in the arraylist items.
- What am i doing wrong to wait until all threads complete?
 - Any other advise, so that the arraylist is returned only after all the 4 threads complete execution.
 
private List GetObjectAttributes(TreeViewAttrs tv)
{
    List objectAttributes = new List();
    string command = "COMMAND_TO_EXECUTE";
    if (command != "")
    {
        List results = RunCommand(command);
        if (results == null) { return null; }
        if (results.Count > 0)
        {
            foreach (string result in results)
            {
                if (!result.Contains("" + tv + ""))
                {
                    string[] res = reformatResponseString(result); //reformat the strings as per custom structure
                    if (res != null) { objectAttributes.Add(res); }
                }
            }
            return objectAttributes;
        }
    }
    return null;
}