2

크게이 질문의 후속 작업으로 test driven asynch tasks 작업 대기가 없다면 작동하는 코드가 생겼습니다.작업. 예외 예외 발생

이유를 설명 할 수 있습니까?

예외 : 코드는 자신의 블로그 TestDriven/w here

public ProgressReporter() 
{ 
    _scheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
} 

Test 'Smack.Core.Presentation.Tests.Threading.ProgressReporterTests.OnSuccessFullComplete_ExpectedResultIsReturned_JustWait' failed: 
System.AggregateException : One or more errors occurred. 
----> System.InvalidOperationException : The current SynchronizationContext may not be used as a TaskScheduler. 
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) 
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) 
at System.Threading.Tasks.Task.Wait() 
Threading\ProgressReporterTests.cs(142,0): at Smack.Core.Presentation.Tests.Threading.ProgressReporterTests.OnSuccessFullComplete_ExpectedResultIsReturned_JustWait() 
--InvalidOperationException 
at System.Threading.Tasks.SynchronizationContextTaskScheduler..ctor() 
at System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext() 
Threading\ProgressReporter.cs(24,0): at Smack.Core.Lib.Threading.ProgressReporter..ctor() 
Threading\ProgressReporterTests.cs(52,0): at Smack.Core.Presentation.Tests.Threading.ProgressReporterTests._startBackgroundTask(Boolean causeError) 
Threading\ProgressReporterTests.cs(141,0): at Smack.Core.Presentation.Tests.Threading.ProgressReporterTests.<OnSuccessFullComplete_ExpectedResultIsReturned_JustWait>b__a() 
at System.Threading.Tasks.Task.InnerInvoke() 
at System.Threading.Tasks.Task.Execute() 

테스트 (NUnit과 스티븐 클리 어리에 의해 작성된 유틸리티 클래스의 생성자를 칠 때

나는이 오류가 발생합니다. 순 주자) :

private class MockSynchContext : SynchronizationContext{} 

[Test] 
public void OnSuccessFullComplete_ExpectedResultIsReturned_Wait() 
{ 
    var mc = new MockSynchContext(); 
    SynchronizationContext.SetSynchronizationContext(mc); 
    Assert.That(SynchronizationContext.Current, Is.EqualTo(mc)); 
    Assert.DoesNotThrow(() => TaskScheduler.FromCurrentSynchronizationContext()); 
    var task = Task.Factory.StartNew(() => _startBackgroundTask(false)); 
    task.Wait(2000); 
    _actualResult = 42; 
} 

SUT에 :

private void _startBackgroundTask(bool causeError) 
{ 
    _cancellationTokenSource = new CancellationTokenSource(); 
    var cancellationToken = _cancellationTokenSource.Token; 
    _progressReporter = new ProgressReporter(); 
    var task = Task.Factory.StartNew(() => 
      { 
       for (var i = 0; i != 100; ++i) { 
        // Check for cancellation 
        cancellationToken.ThrowIfCancellationRequested(); 

        Thread.Sleep(30); // Do some work. 

        // Report progress of the work. 
        _progressReporter.ReportProgress(
         () => 
          { 
           // Note: code passed to "ReportProgress" can access UI elements freely. 
           _currentProgress = i; 
          }); 
       } 

       // After all that work, cause the error if requested. 
       if (causeError) { 
        throw new InvalidOperationException("Oops..."); 
       } 


       // The answer, at last! 
       return 42; 
      }, 
     cancellationToken); 

    // ProgressReporter can be used to report successful completion, 
    // cancelation, or failure to the UI thread. 
    _progressReporter.RegisterContinuation(task,() => 
    { 
     // Update UI to reflect completion. 
     _currentProgress = 100; 

     // Display results. 
     if (task.Exception != null) 
      _actualErrorMessage = task.Exception.ToString(); 
     else if (task.IsCanceled) 
      _wasCancelled = true; 
     else 
      _actualResult = task.Result; 

     // Reset UI. 
     _whenCompleted(); 
    }); 
} 

그냥 명확하게하기 : 내가 task.Wait을 주석 경우 해당 시험은 실제로 성공합니다. 왜 그런가요?

추가 포인트 : 그래서, 나는 이것을 알고

은 기술적으로 또 다른 질문이지만이 모든 것을 반복 수치를 보인다

왜 내 MockSynchContext이 (TaskScheduler.FromCurrentSynchronizationContext에 예외를 발생하지 않았다) 두 번째 과제에서 했습니까? 더 중요한 것은 컨텍스트를 따라 가면서 테스트를 올바르게 수행 할 수있는 방법이 있습니까?

+0

@Stephen Cleary : 어쩌면 스티븐에게 물어봐야 할 것입니다. ;) @alias 기능이 게시물간에 작동하는지 궁금합니다. –

+0

알아 보자 : – Berryl

답변

8

"내가 작업을 주석 처리하면. 실제로 테스트가 성공합니다. 왜 그렇습니까?"

작업은 실제로 작업 ('대기', '값', '처리'등)을 검사 할 때까지 작업 자체에서 발생하는 예외를보고하지 않습니다. 그런 다음 예외를 다시 발생시킵니다. 실제 앱에서는 결국 GC가 작업에 도달하여 앱이 충돌하게됩니다.

+0

마지막으로 편집 된 게시물에 질문을 올렸지 만 의미가 있습니다. 그것에 대한 아이디어는 많이 감사합니다. 건배 – Berryl