이것은 무엇을 의미하며 어떻게 해결합니까?
TPL 작업을 사용하고 있습니다.
전체 오류
Task의 예외는 Task에서 Waiting 또는 Exception 속성에 액세스하여 관찰되지 않았습니다. 결과적으로 관찰되지 않은 예외가 종료 자 스레드에 의해 다시 발생했습니다.
System.Threading.Tasks.TaskExceptionHolder.Finalize ()에서
mscorlib
답변
Task를 생성 하고 가비지 수집기에서 작업을 수집 할 때 task.Wait()
를 호출 하거나 결과를 검색 하지 않는 Task<T>
경우 완료하는 동안 애플리케이션이 해체됩니다. 자세한 내용 은 TPL의 예외 처리에 대한 MSDN 페이지를 참조하십시오 .
여기서 가장 좋은 방법은 예외를 “처리”하는 것입니다. 이 작업은 연속을 통해 수행 할 수 있습니다. 작업에 연속을 연결하고 발생하는 예외를 기록 / 삼킬 수 있습니다. 이것은 작업 예외를 기록하는 깨끗한 방법을 제공하며 간단한 확장 방법으로 작성할 수 있습니다.
public static void LogExceptions(this Task task)
{
task.ContinueWith( t =>
{
var aggException = t.Exception.Flatten();
foreach(var exception in aggException.InnerExceptions)
LogException(exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}
위의 방법을 사용하면 다음을 통해 모든 작업이 앱을 해체하고 로깅하는 것을 방지 할 수 있습니다.
Task.Factory.StartNew( () =>
{
// Do your work...
}).LogExceptions();
또는 TaskScheduler.UnobservedTaskException을 구독 하고 처리 할 수 있습니다.
답변
확실한; 그것은 Task
가비지 콜렉션에 남겨진 후 완료되었지만 태스크 자체가 실패했음을 의미합니다. 두 가지 수정 사항이 있습니다.
- 작업은 (사용 직접 실패 처리
ContinueWith(...)
에 가입하고, 확인.IsFaulted
하고.Exception
온Task
매개 변수에서) TaskScheduler.UnobservedTaskException
이벤트를 처리하고 관찰 됨으로 표시 (e.SetObserved()
오류를 기록한 후 호출 )
답변
이거 한번 해봐:
public static void ThrowFirstExceptionIfHappens(this Task task)
{
task.ContinueWith(t =>
{
var aggException = t.Exception.Flatten();
foreach (var exception in aggException.InnerExceptions)
{
throw exception; // throw only first, search for solution
}
},
TaskContinuationOptions.OnlyOnFaulted); // not valid for multi task continuations
}
public static Task CreateHandledTask(Action action)
{
Task tsk = Task.Factory.StartNew(action);
tsk.ThrowFirstExceptionIfHappens();
return tsk;
}