2016-09-08 3 views
2

다음 코드를 감안할 때 :비동기는 단위 테스트에서 동일한 스레드에서 계속되지 않습니다

public static async void CurrentThreadCall() 
{ 
    Console.WriteLine("Begin on thread {0}", Thread.CurrentThread.ManagedThreadId); 
    await BackgroundCall(); 
    Console.WriteLine("Completed on thread {0}", Thread.CurrentThread.ManagedThreadId); 
} 

private static async Task BackgroundCall() 
{ 
    await Task 
     .Run(() => 
      { 
       Console.WriteLine("Task run on thread: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(TimeSpan.FromMilliseconds(100)); 
      }) 
     .ConfigureAwait(false); 
} 

는 WPF 응용 프로그램에서 CurrentThreadCall() 메서드를 호출을의 시작과 완료 출력은 그냥 것 같은 스레드 (에서 실행됩니다) 기대 :

BackgroundCall begin: 9 
Task run on thread: 6 
Completed on thread 9 <--- As expected 

을 내가 완성 된 출력 대신 작업과 동일한 스레드에서 실행됩니다) 단위 테스트에서 메서드를 호출하고 (VS2015에서 2016.2를 ReSharper에서의의 TestRunner를 사용하는 경우 :

,
Begin on thread 11 
Task run on thread: 4 
Completed on thread 4 <-- Not what I expected 

왜 이런가요, WPF 응용 프로그램과 같이 작동하도록 테스트 할 수 있습니까?

내가 시도 무엇

...

나는 시험 방법 비동기 만들기 위해 노력했다

:

[Test] 
public async Task MyTest() 
{ 
    await CurrentThreadCall(); 
} 

절망에서, 나는 시험에서 set the SynchronizationContext에 시도 :

[Test] 
public void MyTest() 
{ 
    SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); 
    CurrentThreadCall(); 
} 

... 행운을 비네.

답변

2

같은 스레드가 아닌 동일한 동기화 컨텍스트에서 실행을 대기 한 후 작업을 계속합니다. WPF 응용 프로그램의 경우 동기화 컨텍스트가 디스패처와 연결되며 디스패처 스레드가 하나만 있습니다. 따라서 연속은 동일한 스레드에서 실행됩니다. 유닛 테스트에서 동기화 컨텍스트가 없거나 예제에서와 같이 스레드 풀과 연관된 기본 동기화 컨텍스트입니다. 따라서 스레드 풀의 모든 스레드에서 연속이 실행될 수 있습니다.

테스트에서 정확하게 동작을 재현하려면 단일 스레드 동기화 컨텍스트 중 하나, 즉 DispatcherSynchronizationContext 중 하나를 사용해야합니다. https://github.com/StephenCleary/AsyncEx/wiki/AsyncContext

+0

'DispatcherSynchronizationContext'가 작동하지 못했습니다 (예제가 있습니까?),하지만 AsyncContext는 매력처럼 작동합니다. –

+0

다음 페이지에서보십시오 : http://stackoverflow.com/a/20414367/6624113 – dvorn

+1

디스패처 스레드를 실행하고 종료하려면 여러 가지 방법이 있지만 동기화 컨텍스트는 있지만 "쉬운"것은 아닙니다. AsyncContext는 자신과 같은 필요를 위해 의도적으로 만들어졌습니다. – dvorn

관련 문제