Nice programing

TaskCanceledException이 발생하는 이유는 무엇입니까?

nicepro 2021. 1. 8. 22:52
반응형

TaskCanceledException이 발생하는 이유는 무엇입니까?


다음 테스트 코드가 있습니다.

void Button_Click(object sender, RoutedEventArgs e)
{
    var source = new CancellationTokenSource();

    var tsk1 = new Task(() => Thread1(source.Token), source.Token);
    var tsk2 = new Task(() => Thread2(source.Token), source.Token);

    tsk1.Start();
    tsk2.Start();

    source.Cancel();

    try
    {
        Task.WaitAll(new[] {tsk1, tsk2});
    }
    catch (Exception ex)
    {
        // here exception is caught
    }
}

void Thread1(CancellationToken token)
{
    Thread.Sleep(2000);

    // If the following line is enabled, the result is the same.
    // token.ThrowIfCancellationRequested();
}

void Thread2(CancellationToken token)
{
    Thread.Sleep(3000);
}

스레드 방법에서 나는 예외를 포기하지 않는,하지만 난 얻을 TaskCanceledExceptiontry-catch작업을 시작하는 외부 코드의 블록. 이 일이 발생의 목적은 무엇인가 왜 token.ThrowIfCancellationRequested();이 경우는. token.ThrowIfCancellationRequested();스레드 메서드를 호출 하는 경우에만 예외가 throw되어야한다고 생각합니다 .


경쟁 조건의 변형에 직면했기 때문에 이것이 예상되는 동작이라고 생각합니다.

에서 방법 : 작업 및 해당 자식 취소 :

호출 스레드는 작업을 강제로 종료하지 않습니다. 취소가 요청되었음을 알릴뿐입니다. 작업이 이미 실행중인 경우 요청을 확인하고 적절하게 응답하는 것은 사용자 대리인의 몫입니다. 작업이 실행되기 전에 취소를 요청하면 사용자 위임이 실행되지 않고 작업 개체가 Canceled상태 로 전환됩니다 .

그리고 작업 취소에서 :

델리게이트에서 돌아와서 [...] 작업을 종료 할 수 있습니다. 많은 시나리오에서 이것으로 충분합니다. 그러나 이러한 방식으로 "취소"된 태스크 인스턴스는 RanToCompletion상태가 아닌 상태로 전환됩니다 Canceled.

My educated guess here is that while you are calling .Start() on your two tasks, chances are that one (or both of them) didn't actually start before you called .Cancel() on your CancellationTokenSource. I bet if you put in at least a three second wait between the start of the tasks and the cancellation, it won't throw the exception. Also, you can check the .Status property of both tasks. If I'm right, the .Status property should read TaskStatus.Canceled on at least one of them when the exception is thrown.

Remember, starting a new Task does not guarantee a new thread being created. It falls to the TPL to decide what gets a new thread and what is simply queued for execution.

ReferenceURL : https://stackoverflow.com/questions/15181855/why-does-taskcanceledexception-occur

반응형