2012-12-14 2 views
0

다음의 간단한 코드를 고려한 후 질문을 드리겠습니다.테스트 코드 - 테스트 환경에서 스레딩을 우회하는 방법

public static void Save(XmlDocument saveBundle) 
    { 
     ThreadStart threadStart = delegate 
     { 
      SaveToDatabase(saveBundle); 
     }; 

     new Thread(threadStart).Start();    
    } 

비주얼 스튜디오 (2005)에서 스레드를 사용하는 데 문제는 내가 내가이 바라고 있어요으로 들여다하지 않은 스레드를 전환하는 방법이 생각 (쉽게를 통해 걸을 수 없다 더 쉬운 방법).

라이브에서 내 코드는 위의 예보다 복잡하며 시간이 중요하기 때문에 새 스레드를 사용하지만 주체는 동일합니다. 가장 중요한 것은 테스트에서 시간이 중요하지 않습니다!

현재로서는 #if debug을 사용하는 것과 같은 일을 할 것입니다.하지만 올바른 방법으로 #if를 사용하고 있습니까? 아니면이 문제를 해결할 더 좋은 방법이 있습니까?

public static void Save(XmlDocument saveBundle) 
    { 

    #if debug 
     { 
     SaveToDatabase(parameters); 
     } 
    #else 
     { 
      ThreadStart threadStart = delegate 
      { 
       SaveToDatabase(parameters); 
      }; 

      new Thread(threadStart).Start(); 
     } 
    #endif 
     } 
    } 

내가 .NET 2.0 난 이후 .NET (20)의 모든 버전에 관심이 붙어있어 있지만

답변

1

경우 :

public static void Save(XmlDocument saveBundle, Action<Exception> completedCallback) 
{ 
    ThreadStart threadStart = delegate 
    { 
     try 
     {    
      SaveToDatabase(saveBundle); 
      completedCallback(null); 
     } 
     catch (Exception ex) 
     { 
      completedCallback(ex); 
     } 
    }; 

    new Thread(threadStart).Start();    
} 

그런 식으로, 당신은 당신의 단위 테스트를 조율하기 위해 동기화 방법의 일종을 사용할 수 있습니다 당신이 정말로하고 싶은 것은 디버그 빌드에서 스레딩을 사용하지 않는 것입니다. 이것이 올바른 방법이며 아마 가장 빠르고 유능한 방법이기도합니다. 약간 엉망으로 보일지 모르지만 대안은 더 많은 bool, 구성 및 기타 해결 방법입니다.

스레드를 직접 디버깅하는 데 관심이있는 경우 (동시성이 문제 일 때 중요합니다! 가능한 한 프로덕션 환경에 가까운 상태로 테스트해야합니다.) 디버그 -> Windows -> 스레드)를 선택하고 디버그 할 스레드와 "스레드로 전환"을 마우스 오른쪽 단추로 클릭하십시오.

2
(I 언젠가 내가 쥐라기을 떠나 다른 사람에 가입 거라고 확신)

원래 코드에는 중요한 기능이 없습니다. 다시보고 메커니즘의 일종는 작업을 완료 (또는 실패) 때 :

Exception actualException = null; 
using (AutoResetEvent waitHandle = new AutoResetEvent(false)) 
{ 

    instance.Save(xmlDocument, ex => 
    { 
     actualException = ex; 
     waitHandle.Set(); 
    }); 
    waitHandle.WaitOne(); 
} 

Assert.IsNull(actualException); 
0

아마도이 스레딩 코드를 별도의 메서드에 넣고 테스트 할 때이 메서드로 대체 할 수 있습니다.

virtual void SaveToDBInSeparateThread(...) 
{ 
    ThreadStart threadStart = delegate 
    { 
     ... 
    }; 

    new Thread(threadStart).Start(); 
} 

그런 다음 void를 반환하는 대신 스레드 실행 또는 비슷한 것을 반환 할 수 있습니다.

또는 아래처럼 메서드에 입력 매개 변수를 추가 할 수 있습니다

virtual void SaveToDB(bool inSeparateThread) 
{ 
    if(inSeparateThread) 
    { 
     ThreadStart threadStart = delegate 
     { 
     ... 
     }; 

     new Thread(threadStart).Start(); 
    } 
    ... 
} 

또는 당신은 DatabaseSavingContext 어떤 종류의 제공 할 수 있습니다 스레드가 아닌 스레드 다른 구현을 (

interface IDBSaveContext 
{ 
    public void SaveToDB(...) 
} 

를 사용)이 실행 유형에 따라이 인터페이스의.

+0

부울은 조건부와 거의 동일하며 추가 오버 헤드를 추가합니다. –

+0

네, 맞습니다. 질문의 저자가 전처리 조건부를 사용하는 것이 불편하다고 느끼기 때문에 방금 그런 옵션을 제안했습니다. –

관련 문제