2013-07-24 123 views
-1

我寫了下面的代碼。在那裏我創建了兩個線程ItmTh和RelTh。 ItmTh線程應該先執行,並且當ItmTh線程完成其執行時,應執行RelTh線程。可能的解決方案是什麼?多線程和線程同步

`

   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();` 
+0

請看看[這](http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net)。在那裏你有5種不同的選擇來說明如何去做你想做的事。 – Steven

+0

謝謝我檢查它。 –

+0

點擊「this」一詞。它是一個LinkLabel。但是,如果你願意,有一個完整的鏈接:http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net。 – Steven

回答

2

可以使用Tasks代替Threads - 創建多個線程僅僅是一個開銷 - 你的電腦很可能沒有那麼多CPU內核。 TasksTask Parallel Library嘗試到確保您按照硬件運行正確的線程數。

//... 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. 
       }); 

     }); 
    }); 
+0

TPL需要.NET 4或更高版本。 TPL只是.NET 4 + ThreadPool的一個抽象層,因此兩者之間的結果基本相同。因此,ThreadPool和TPL可以擁有比系統硬件支持的線程多得多的線程。 CPU硬件線程數,所以你最後的評論是誤導。 – deegee

+0

@deegee:我沒有比較'ThreadPool'和'TPL'。 OP正在創建自己的'Threads' - 不使用'ThreadPool'。儘管如此,建議在Fire和Forget函數中使用ThreadPool API,但OP想要在線程之間等待和同步。當然''ThreadPool'中的線程數可能比硬件線程多 - 但創建新的'Tasks'不會創建相同數量的新'線程' - 它會在現有的'ThreadPool'線程上調度'Tasks'。 – YK1

+0

@deegee:我在'確保'前加了'嘗試' - 也許現在更有意義了? – YK1