/**
  * Creates threads, executes them, then wait till
  * each thread is finished
  *
  * @param test         Test definition
  * @param classId      Class id specifying the implementation of test scenario
  */
 static void createRunJoinThreads(PerformanceTestResult test, int classId)
 {
     test.testInit();
     TestThread[] runners = new TestThread[test.threadsNum];
     Thread[] threads = new Thread[test.threadsNum];
     for (int threadId = 0; threadId < test.threadsNum; threadId++) {
         switch (classId) {
         case 0:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 1:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 2:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 3:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 4:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 5:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 6:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 7:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 8:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 9:  runners[threadId] = new TestSimpleCalcThread(test); break;
         case 10: runners[threadId] = new TestSimpleCalcThread(test); break;
         case 11: runners[threadId] = new Test011Thread(test); break;
         case 12: runners[threadId] = new Test012Thread(test); break;
         case 13: runners[threadId] = new Test013Thread(test); break;
         case 14: runners[threadId] = new Test014Thread(test); break;
         case 15: runners[threadId] = new Test015Thread(test); break;
         case 16: runners[threadId] = new Test016Thread(test); break;
         case 17: runners[threadId] = new Test017Thread(test); break;
         case 18: runners[threadId] = new Test018Thread(test); break;
         case 19: runners[threadId] = new Test019Thread(test); break;
         case 20: runners[threadId] = new Test020Thread(test); break;
         }
         threads[threadId] = new Thread(runners[threadId].run);
         threads[threadId].Start();
     }
     for (int threadId = 0; threadId < test.threadsNum; threadId++)
         try {
             threads[threadId].Join();
         } catch (ThreadInterruptedException e) {
             Console.WriteLine(e.StackTrace);
         }
     test.testClose();
 }
        /**
         * Creates threads, executes them, then wait till
         * each thread is finished
         *
         * @param test         Test definition
         * @param classId      Class id specifying the implementation of test scenario
         */
        static void createRunJoinThreads(PerformanceTestResult test, int classId)
        {
            test.testInit();
            TestThread[] runners = new TestThread[test.threadsNum];
                        #if !PCL && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6
            Thread[] threads = new Thread[test.threadsNum];
                        #endif
            for (int threadId = 0; threadId < test.threadsNum; threadId++)
            {
                switch (classId)
                {
                case 0:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 1:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 2:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 3:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 4:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 5:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 6:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 7:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 8:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 9:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 10: runners[threadId] = new TestSimpleCalcThread(test); break;

                case 11: runners[threadId] = new Test011Thread(test); break;

                case 12: runners[threadId] = new Test012Thread(test); break;

                case 13: runners[threadId] = new Test013Thread(test); break;

                case 14: runners[threadId] = new Test014Thread(test); break;

                case 15: runners[threadId] = new Test015Thread(test); break;

                case 16: runners[threadId] = new Test016Thread(test); break;

                case 17: runners[threadId] = new Test017Thread(test); break;

                case 18: runners[threadId] = new Test018Thread(test); break;

                case 19: runners[threadId] = new Test019Thread(test); break;

                case 20: runners[threadId] = new Test020Thread(test); break;
                }
                                #if PCL || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6 || NETCOREAPP1_0 || NETCOREAPP1_1
                runners[threadId].run();
                                #else
                threads[threadId] = new Thread(runners[threadId].run);
                threads[threadId].Start();
                                #endif
            }
                        #if !PCL && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && NETCOREAPP1_0 && NETCOREAPP1_1
            for (int threadId = 0; threadId < test.threadsNum; threadId++)
            {
                try {
                    threads[threadId].Join();
                } catch (ThreadInterruptedException e) {
                    mXparser.consolePrintln(e.StackTrace);
                }
            }
                        #endif
            test.testClose();
        }
        /**
         * Creates threads, executes them, then wait till
         * each thread is finished
         *
         * @param test         Test definition
         * @param classId      Class id specifying the implementation of test scenario
         */
        static void createRunJoinThreads(PerformanceTestResult test, int classId)
        {
            test.testInit();
            TestThread[] runners = new TestThread[test.threadsNum];
            Thread[]     threads = new Thread[test.threadsNum];
            for (int threadId = 0; threadId < test.threadsNum; threadId++)
            {
                switch (classId)
                {
                case 0:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 1:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 2:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 3:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 4:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 5:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 6:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 7:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 8:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 9:  runners[threadId] = new TestSimpleCalcThread(test); break;

                case 10: runners[threadId] = new TestSimpleCalcThread(test); break;

                case 11: runners[threadId] = new Test011Thread(test); break;

                case 12: runners[threadId] = new Test012Thread(test); break;

                case 13: runners[threadId] = new Test013Thread(test); break;

                case 14: runners[threadId] = new Test014Thread(test); break;

                case 15: runners[threadId] = new Test015Thread(test); break;

                case 16: runners[threadId] = new Test016Thread(test); break;

                case 17: runners[threadId] = new Test017Thread(test); break;

                case 18: runners[threadId] = new Test018Thread(test); break;

                case 19: runners[threadId] = new Test019Thread(test); break;

                case 20: runners[threadId] = new Test020Thread(test); break;
                }
                threads[threadId] = new Thread(runners[threadId].run);
                threads[threadId].Start();
            }
            for (int threadId = 0; threadId < test.threadsNum; threadId++)
            {
                try {
                    threads[threadId].Join();
                } catch (ThreadInterruptedException e) {
                    Console.WriteLine(e.StackTrace);
                }
            }
            test.testClose();
        }