2014-12-12 2 views
0

여기에 문제가 있습니다. 프로그래밍 방식으로 특정 스레드가 종료되는 순간을 찾을 수 있습니까? 제 말은 VS 디버거조차도 출력 창에 정보를 제공한다는 것입니다. 내 스레드가 단순히 이벤트를 발생시킬 수 있다는 것을 알고 있지만 둘 이상의 스레드를 생성 할 때 문제가 발생하므로 토글 변수를 사용하지 않는 한 각각의 이벤트가 발생합니다. 코드에서 해당 지점에 도달하는 첫 번째 스레드는 이벤트를 발생시킵니다.특정 스레드가 종료 될 때를 찾는 방법 (C#)?

여기에 표시된 취소, 일시 중지 및 종료 논리를 사용하여 여러 스레드에서 실행되는 메소드의 시작 부분입니다. 코드의 문제점은 이벤트 핸들러 (DownloadComplete, DownloadPaused 및 DownloadCanceled)에 대한 호출입니다. 보시다시피, 그 중 일부는 해당 지점에 도달 한 첫 번째 스레드에 의해 한 번만 실행되고 관련 bool 변수는 토글되므로 다른 스레드는이 이벤트를 다시 발생시키지 않습니다. 여기서 또 다른 큰 문제는 스레드 종료 로직으로, 스레드가 다운로드 할 항목을 찾지 못했을 때 각 스레드에 의해 실행되는 다운로드 완료 이벤트가 다시 발생하는 경우 반환됩니다. 이 두 가지 방법 모두 올바르지 않으며 현재 의도 한 동작을 구현하는 방법을 알지 못합니다. 내가 필요한 것은 모든 스폰 된 스레드가 끝날 때 momement를 잡는 방법을 찾아내는 방법을 찾는 단서를 가지고있어서 위에서 언급 한 모든 이벤트를 한 번만 올릴 수 있다는 것입니다.

내 프로젝트는 .net 2.0을 대상으로하므로 System.Threading.Tasks 네임 스페이스의 형식에는 액세스 할 수 없습니다. 이것은 어떤 수업 과제보다 더 복잡한 무언가를 프로그래밍하는 것에 대한 나의 첫 경험입니다. 그래서 나는이 코드가 모든 종류의 끔찍한 일이라는 것을 알고 있습니다.

영어로 죄송합니다.

private void PerformDownload() 
    { 
     while (true) 
     { 
      if (askedToCancel) 
      { 
       lock (lockObj) 
       { 
        if (!cancellationPerformed) 
        { 
         cancellationPerformed = true; 

         foreach (DownloadItem di in itemsToProcess) 
          if (di.Status == DownloadItemStatus.Prepared) 
           itemsToProcess.UpdateItemStatus(di.URL, DownloadItemStatus.Canceled); 

         DownloadCanceled(); 
        } 
       } 

       return; 
      } 

      if (askedToPause) 
      { 
       lock (lockObj) 
       { 
        if (!pausingPerformed) 
        { 
         foreach (DownloadItem di in itemsToProcess) 
          if (di.Status == DownloadItemStatus.Prepared) 
           itemsToProcess.UpdateItemStatus(di.URL, DownloadItemStatus.Paused); 

         DownloadPaused(); 
        } 
       } 

       waitHandle.WaitOne(); 
      } 

      DownloadItem currentItem = null; 

      lock (lockObj) 
      { 
       foreach (DownloadItem di in itemsToProcess) 
        if (di.Status == DownloadItemStatus.Prepared) 
        { 
         currentItem = di; 
         itemsToProcess.UpdateItemStatus(currentItem.URL, DownloadItemStatus.Downloading); 
         break; 
        } 
      } 

      if (currentItem == null) 
      { 
       DownloadComplete(); 
       return; 
      } 

답변

1

당신은 때 스레드가 종료를 감소시키는 스레드의 진입 점에서 증가, 카운터에 Interlocked.Increment()Interlocked.Decrement()를 사용할 수 있습니다. 그런 다음 카운터가 0이 아니면 적어도 하나의 해당 스레드 인스턴스가 실행 중입니다. 예를 들어

: 말했다

private int _threadCounter; 

private void ThreadEntryPoint() 
{ 
    try 
    { 
     Interlocked.Increment(ref _threadCounter); 
     // Do thread stuff here 
    } 
    finally 
    { 
     Interlocked.Decrement(ref _threadCounter); 
    } 
} 

, 그것은 이럴 스레드가 실행 여부 문제에 대한 최고의 디자인이 될 가능성이 없습니다. 즉, 그 정보가 어떻게 사용될 수 있는지 생각할 때마다 시나리오를 다루는 더 좋은 방법이있는 것 같습니다.

스레드는 단순히 존재하는 것 이상의 이유로 존재합니다. 그래서 코드가 정말로 신경 써야 할 것은 스레드가 실행 중인지 여부가 아니라 그 이유가 해결되었는지 여부입니다. 완전한 코드 예제가 없으면 특정 시나리오에 대해서는 언급 할 수 없습니다. 그러나 실제 스레드 존재를 추적하는 것이 덜 유용하고보다 목표 지향적 인 방법보다 유지 관리가 더 어려울 것으로 생각됩니다.

+0

글쎄, try-catch 안에 threaded 메소드의 전체 코드를 넣는 것은 너무 많은 일이지만, 나는 당신이 제안한 방식으로 활성 쓰레드를 계산하려고 시도 할 것이다. – Taps

관련 문제