2013-02-05 4 views
2

데이터를 추출하는 큰 디렉토리에서 실행되고 언어 코드 당 스레드 (디렉토리의 첫 번째 레벨)를 시작하는 도구를 만들고 있습니다. 도구가 교착 상태에 빠졌기 때문에 모든 스레드가 완료 될 때까지 데이터베이스에 스레드가 추가되지 않도록 루프를 추가했습니다. 그러나이 데이터를 테스트 할 때 테스트 데이터가 정적 인 경우에도 DB는 잘못된 언어를 저장합니다. 예를 들어 67 개 언어가 있지만 DB에는 48 개 언어 만 있습니다. 나는 문제가 스레드가 중지되기 전에 진행에서 프로그램을 중지하기위한 내 루프가 깨진 수 있습니다 생각, 즉. 그것은 모든 쓰레드가 멈추기 전에 DB에 파일을 추가함으로써 길을 따라 언어를 잃어 버리게됩니다. 나는이 문제를 해결하는 방법을 아는 사람이 없다고 생각하지 않습니까? 감사.정적 데이터로 다른 값을 반환하는 스레드

//get the languages from the folders 
     string[] filePaths = Directory.GetDirectories(rootDirectory); 
     for (int i = 0; i < filePaths.Length; i++) 
     { 
      string LCID = filePaths[i].Split('\\').Last(); 
      Console.WriteLine(LCID); 
      //go through files in each folder and sub-folder with threads 
      Thread t1 = new Thread(() => new HBScanner(new DirectoryInfo(filePaths[i - 1])).HBscan()); 
      t1.Start(); 
      threads.Add(t1); 
     } 

     // wait for all threads to complete before proceeding 
     foreach (Thread thread in threads) 
     { 
      while (thread.ThreadState != ThreadState.Stopped) 
      { 
       //wait 
      } 
     } 
+0

filePaths [i - 1] - 어떻게 작동합니까? –

+0

개별 스레드 대신'작업 '을 사용하는 것이 좋습니다. 이러한 종류의 구성은 쉽게 제어 할 수 없으며 수백 또는 수천 개의 스레드를 회전시킬 수 있습니다. 또한, 루프하고 기다리는 경우, 어떤 종류의 WaitHandle을 사용하거나'ThreadState == ThreadState.Running'을 검사 할 수있다. 스레드가 Stopped 대신에 입력 할 수있는 많은 다른 상태가 있습니다. – CodingGorilla

+0

필자는 filepaths [I-1]이없고 filepaths [I]가있을 때 "배열의 범위를 벗어나는 색인"오류가 발생했을 때 해결책을 찾은 후 해결책이 [I-1] 인 것처럼 보였습니다 – RebeccaD

답변

2

우선 경로의 로컬 복사본을 만들어 for-loop 변수 대신 스레드로 전달하십시오. Closing over the loop variable is considered harmful.

인덱스가 범위를 벗어나는 이유는 모르겠지만 foreach -loop을 사용하면이를 피할 수 있습니다.

//get the languages from the folders 
string[] filePaths = Directory.GetDirectories(rootDirectory); 
foreach(string filePath in filePaths) 
{ 
    Console.WriteLine(filePath.Split('\\').Last()); 

    string tmpPath = filePath; // <-- local copy 

    //go through files in each folder and sub-folder with threads 
    Thread t1 = new Thread(() => new HBScanner(new DirectoryInfo(tmpPath)).HBscan()); 
    t1.Start(); 
    threads.Add(t1); 
} 

두 번째 : 사용자 지정 대기 코드 대신 use Join on the threads입니다.

// wait for all threads to complete before proceeding 
foreach (Thread thread in threads) 
{ 
    thread.Join(); 
} 

마지막으로 데이터베이스에 경합이 없는지 확인하십시오. HBScanner에 대한 자세한 정보가 없으면이 문제의 원인에 대해 다른 말을하기가 어렵습니다.

+0

고마워 이것이 문제를 해결 한 것 같다! – RebeccaD

+0

이 조인 함수는 어떻게 작동합니까? 나는 그것을 문서에서 이해하려고 노력하고 있지만 그것을 완전히 설명하는 것을 볼 수는 없다. –

+0

나는 스레드가 종료되었음을 확신하는 한 100 % 확실하지 않습니다. 스레드가 종료되지 않고 Join이 호출 될 때 스레드가 이미 종료 된 경우에는 무한정 차단되며 메서드는 즉시 반환됩니다. – RebeccaD