-1

I have written following code. In that I have created two threads ItmTh and RelTh. ItmTh threads should be executed first and when ItmTh thread finish its execution RelTh thread should be executed.What is possible solution?

`

                string[] filePaths = Directory.GetFiles(folderPath, "ARAS_IT*");
                bool isTemplateFile = true;
                int arasDefinitionFileCount = filePaths.Length;
                TotalTemplateFile = arasDefinitionFileCount + Directory.GetFiles(folderPath, "ARAS_Rel*").Length;

                //progressBar1.Value=0;
                //int progess = 0;

                if (arasDefinitionFileCount < 1)
                {
                    isTemplateFile = false;
                    //MessageBox.Show("Root Folder does not contain Template File");
                    //return;
                }

                ManualResetEvent syncEvent = new ManualResetEvent(false);

                Thread ItmTh = new Thread(()=> 
                    {


                        //Iterate over Item Type files in Root Folder
                        for (int i = 0; i < arasDefinitionFileCount; i++)
                        {
                            //progess++;
                            //UpdateProgress(Convert.ToInt32(Convert.ToDouble((progess * 100) / progressBarValue)));
                            string fileName = filePaths[i];
                            //Find Name of Item Type From File Name
                            string ItemType = Path.GetFileNameWithoutExtension(fileName);
                            int start = ItemType.LastIndexOf('-');
                            int end = ItemType.Length;
                            start++;
                            end = end - start;
                            ItemType = ItemType.Substring(start, end);
                            //UpdateProgress(0);

                            if (ItemType.Equals("Document", StringComparison.InvariantCultureIgnoreCase))
                            {
                                Thread th = new Thread(() =>
                                    {
                                        processDocumentDataDefinitionFile(fileName, folderPath + "\\ARAS_IT-" + ItemType + "-files\\");

                                    });
                                th.Start();
                                //th.Join();
                            }
                            else
                            {
                                Thread th = new Thread(() =>
                                    {
                                       processDataDefinitionFile(fileName, tbRootFolderPath.Text, ItemType, folderPath + "\\ARAS_IT-" + ItemType + "-files\\");

                                    });
                                th.Start();
                                //Wait for Previous thread To complete its task
                                //th.Join();
                            }



                        }

                     });

                ItmTh.Start();
                /*******************************************************************************************************************/
                //Process Relationship files
                //ItmTh.Join();
                Thread RelTh = new Thread(()=> 
                    {

                        syncEvent.WaitOne();
                        filePaths = null;
                        filePaths = Directory.GetFiles(folderPath, "ARAS_Rel*");

                        arasDefinitionFileCount = filePaths.Length;

                        if (arasDefinitionFileCount < 1 && isTemplateFile == false)
                        {
                            MessageBox.Show("Root Folder does not contain Template File");
                            return;
                        }

                        //Iterate over Relationships files in Root Folder
                        for (int i = 0; i < arasDefinitionFileCount; i++)
                        {
                            string fileName = filePaths[i];

                            //Find Name of Item Type From File Name
                            string ItemType = Path.GetFileNameWithoutExtension(fileName);
                            int start = ItemType.LastIndexOf('-');
                            int end = ItemType.Length;
                            start++;
                            end = end - start;
                            ItemType = ItemType.Substring(start, end);

                            //Process File
                            Thread th = new Thread(() =>
                            {
                                Cursor.Current = Cursors.WaitCursor;

                                processDataDefinitionFile(fileName, tbRootFolderPath.Text, ItemType, folderPath + "\\ARAS_IT-" + ItemType + "-files\\");

                            });
                            th.Start();
                            //Wait for Previous thread To complete its task
                            // th.Join();

                        }

                    });

                        RelTh.Start();`
  • Please, have a look at [this](http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net). There you have 5 different options on how to do what you want. – Steven Jul 24 '13 at 11:16
  • Click on the word 'this'. It is a LinkLabel. But if you wish, there is a full link: http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net . – Steven Jul 24 '13 at 11:24
  • I have already check that link and i have tried but something is wrong please let me know where is my mistake in that code? – Amit Nawale Jul 24 '13 at 11:32
  • You have a problem with your code? Please describe the problem. What is wrong? – Dialecticus Jul 24 '13 at 11:38
  • Problem is that Itm thread should be executed first and completed its execution then RelTh should start its execution – Amit Nawale Jul 24 '13 at 12:25
  • 3
    Rather than post all your code, it would be beneficial to reduce the code to its essence - the smallest possible snippet of code you can create to demonstrate the problem. http://sscce.org/ – Jeff B Jul 24 '13 at 12:47

1 Answers1

2

You can use Tasks instead of Threads - creating many threads is just an overhead - your computer most probably does not have that many CPU cores. Tasks and Task Parallel Library try to ensure you are running right amount of threads as per your hardware.

//... your code ...
Task ItmTask = new Task.Factory.StartNew(()=> 
    {
        Task[] subTasks = new Task[arasDefinitionFileCount];

        for (int i = 0; i < arasDefinitionFileCount; i++)
        {
            //... your code...

            if (ItemType.Equals("Document", StringComparison.InvariantCultureIgnoreCase))
            {
                subTasks[i] = new Task.Factory.StartNew(() =>
                    {
                        processDocumentDataDefinitionFile(fileName, folderPath + "\\ARAS_IT-" + ItemType + "-files\\");

                    });
            }
            else
            {
                subTasks[i] = new Task.Factory.StartNew(() =>
                    {
                       processDataDefinitionFile(fileName, tbRootFolderPath.Text, ItemType, folderPath + "\\ARAS_IT-" + ItemType + "-files\\");

                    });
            }
        }

         // Continue when all sub tasks are done
        Task.Factory.ContinueWhenAll(subTasks, _ => 
         {
            // Cursor.Current = Cursors.WaitCursor;

            // .... your code ....

            Task[] subTasks2 = new Task[arasDefinitionFileCount];

            for (int i = 0; i < arasDefinitionFileCount; i++)
            {
                subTasks2[i] = new Task.Factory.StartNew(() =>
                {
                    processDataDefinitionFile(fileName, tbRootFolderPath.Text, ItemType, folderPath + "\\ARAS_IT-" + ItemType + "-files\\");

                });

            }

            Task.Factory.ContinueWhenAll(subTasks2, __ => 
              {
                 // reset cursor to normal etc.
              });

         });
     });
YK1
  • 7,327
  • 1
  • 21
  • 28
  • TPL requires .NET 4 or higher. TPL is simply an abstraction layer over the .NET 4+ ThreadPool, so the results between the two are essentially the same. ThreadPool, and therefor TPL, can have significantly more threads than what the system hardware supports ie. the CPU hardware thread count, so your last comment is misleading. – deegee Jul 24 '13 at 18:41
  • @deegee: I have not compared `ThreadPool` and `TPL`. OP is creating his own `Threads` - not using `ThreadPool`. Nevertheless, `ThreadPool` API are recommended for Fire and Forget functions - but OP wants to Wait and sync betweeen threads. Sure you can have more threads in `ThreadPool` than hardware threads - but creating new `Tasks` does not create equal number of new `Threads` - it schedules the `Tasks` on existing `ThreadPool` threads. – YK1 Jul 24 '13 at 19:00
  • @deegee: I added `try to` in front of `ensure` - perhaps it makes more sense now? – YK1 Jul 24 '13 at 19:03
  • So the short answer is that in case of TPL (which I also recommend) someone can simply chain tasks using `ContinueWith`. With TPL there's also nice way to handle exceptions. – Csaba Toth Jul 24 '13 at 19:42
  • Thanks you all for your suggestions – Amit Nawale Jul 25 '13 at 05:35