2016-10-18 3 views
4

나는 작업과 async/await를 사용하여 작업을 반복하는 방법을 가지고있다. 나는 실패이 테스트를 기대하고이 작업을 테스트하는 올바른 방법은 무엇입니까?

[TestMethod, TestCategory("Unit")] 
    public async Task Should_do_repeating_work_and_rethrow_exceptions() 
    { 
     Action work =() => 
     { 
      throw new Exception("Some other exception."); 
     }; 

     var task = work.ToRepeatingWork(1); 
     task.Start(); 
     await task; 
    } 

하지만, 전달 (시험 주자 충돌) :

public static Task ToRepeatingWork(this Action work, int delayInMilliseconds) 
    { 
     Action action = async() => 
     {     
      while (true) 
      { 
       try 
       { 
        work(); 
       } 
       catch (MyException ex) 
       { 
        // Do Nothing 
       } 
       await TaskEx.Delay(new TimeSpan(0, 0, 0, 0, delayInMilliseconds)); 
      } 
     }; 
     return new Task(action, SomeCt, TaskCreationOptions.LongRunning); 
    } 

나는 해당 테스트를 작성했습니다.

그러나 ToRepeatingWork 메서드에서 작업을 async에서 일반 작업으로 변경하고 기다리는 대신 기다리면 테스트가 예상대로 작동합니다.

TaskEx.Delay(new TimeSpan(0, 0, 0, 0, delayInMilliseconds)).Wait(); 

무엇이 잘못 되었나요?

+7

'TaskEx'? '예'? 2016 년에 여전히 비동기 * 미리보기 *를 사용하고 있다고 하시겠습니까? –

+1

'Waiting work.ToRepeatingWork (1);', While 루프가 종료 될 때 명시 적으로 시작하는 대신 –

+0

'TaskEx'처럼 보일 수 있습니다. 우리는 .Net 4.0에서 실행되도록 애플리케이션이 필요합니다. 지연 및 실행을 사용할 수 있도록 TaskEx 사용. –

답변

1

결코 작업 생성자를 사용해서는 안됩니다. 스레드 풀에 배치 할 작업이 있다면 Task.Run을 사용하십시오. 이것은 문제이지만 충돌을 일으키는 원인은 아닙니다.

또한 async void을 피해야하므로 Action 대신 Func<Task>을 사용하십시오. 이것은 충돌의 원인입니다.

public static Task ToRepeatingWork(this Action work, int delayInMilliseconds) 
{ 
    Func<Task> action = async() => 
    {     
    while (true) 
    { 
     try 
     { 
     work(); 
     } 
     catch (MyException ex) 
     { 
     // Do Nothing 
     } 
     await TaskEx.Delay(new TimeSpan(0, 0, 0, 0, delayInMilliseconds)); 
    } 
    }; 
    return Task.Run(() => action()); 
} 

[TestMethod, TestCategory("Unit")] 
public async Task Should_do_repeating_work_and_rethrow_exceptions() 
{ 
    Action work =() => 
    { 
    throw new Exception("Some other exception."); 
    }; 

    var task = work.ToRepeatingWork(1); 
    await task; 
} 
+0

은 Task.Run에 전달 된 lambda를 async로 표시하지 않은 이유는 무엇입니까? 이것과'Task.Run (async() => await action())'의 차이점은 무엇입니까? 도움을 주셔서 감사합니다 –

+0

@SharePointNewbie : [그것은 같은 것입니다] (http://stackoverflow.com/questions/19098143/what-is-the-purpose-of-return-await-in-c). –

관련 문제