다음을 통해 공유


작업 취소

System.Threading.Tasks.Task 클래스는 System.Threading.Tasks.Task<TResult> 취소 토큰을 사용하여 취소를 지원합니다. 자세한 내용은 관리되는 스레드에서 취소을 참조하세요. 작업 클래스에서 취소에는 취소 가능한 작업을 나타내는 사용자 대리자와 취소를 요청한 코드 간의 협력이 포함됩니다. 성공적인 취소에는 메서드를 호출 CancellationTokenSource.Cancel 하는 요청 코드와 사용자 대리자가 적시에 작업을 종료하는 작업이 포함됩니다. 다음 옵션 중 하나를 사용하여 작업을 종료할 수 있습니다.

  • 대리인으로부터 반환합니다. 많은 시나리오에서 이 옵션은 충분합니다. 그러나 이러한 방법으로 취소된 작업 인스턴스는 TaskStatus.RanToCompletion 상태로 전환되며 TaskStatus.Canceled 상태로는 전환되지 않습니다.

  • 취소를 OperationCanceledException throw하여 취소가 요청된 토큰을 전달합니다. 선호되는 방법은 ThrowIfCancellationRequested 메서드를 사용하는 것입니다. 이러한 방식으로 취소된 작업은 취소됨 상태로 전환되며, 호출 코드는 태스크가 취소 요청에 응답했는지 확인하는 데 사용할 수 있습니다.

다음 예제에서는 예외를 throw하는 작업 취소에 대한 기본 패턴을 보여 줍니다.

비고

토큰은 사용자 대리자 및 작업 인스턴스에 전달됩니다.

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Run(() =>
        {
            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            while (moreToDo)
            {
                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }
            }
        }, tokenSource2.Token); // Pass same token to Task.Run.

        tokenSource2.Cancel();

        // Just continue on this thread, or await with try-catch:
        try
        {
            await task;
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
        finally
        {
            tokenSource2.Dispose();
        }

        Console.ReadKey();
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module Test
    Sub Main()
        Dim tokenSource2 As New CancellationTokenSource()
        Dim ct As CancellationToken = tokenSource2.Token

        Dim t2 = Task.Factory.StartNew(Sub()
                                           ' Were we already canceled?
                                           ct.ThrowIfCancellationRequested()

                                           Dim moreToDo As Boolean = True
                                           While moreToDo = True
                                               ' Poll on this property if you have to do
                                               ' other cleanup before throwing.
                                               If ct.IsCancellationRequested Then

                                                   ' Clean up here, then...
                                                   ct.ThrowIfCancellationRequested()
                                               End If

                                           End While
                                       End Sub _
        , tokenSource2.Token) ' Pass same token to StartNew.

        ' Cancel the task.
        tokenSource2.Cancel()

        ' Just continue on this thread, or Wait/WaitAll with try-catch:
        Try
            t2.Wait()

        Catch e As AggregateException

            For Each item In e.InnerExceptions
                Console.WriteLine(e.Message & " " & item.Message)
            Next
        Finally
            tokenSource2.Dispose()
        End Try

        Console.ReadKey()
    End Sub
End Module

전체 예제를 보려면 작업 및 그 하위 작업 취소 방법을 참조하세요.

태스크 인스턴스가 사용자 코드에 의해 throw된 OperationCanceledException을(를) 관찰하면, 예외의 토큰을 작업을 생성한 API에 전달된 연결된 토큰과 비교합니다. 토큰이 동일하고 토큰의 IsCancellationRequested 속성이 반환 true되면 태스크는 이를 취소를 인정하는 것으로 해석하고 취소됨 상태로 전환합니다. 작업을 기다리는 데 Wait 또는 WaitAll 메서드를 사용하지 않는 경우, 작업은 상태를 Canceled로 설정합니다.

취소됨 상태로 System.Threading.Tasks.TaskCanceledException 전환되는 작업을 기다리는 경우 AggregateException 예외에 래핑된 예외가 발생합니다. 이 예외는 잘못된 상황이 아닌 성공적인 취소를 나타냅니다. 따라서 작업의 Exception 속성이 반환됩니다 null.

토큰의 IsCancellationRequested 속성이 반환 false 되거나 예외의 토큰이 작업의 토큰 OperationCanceledException 과 일치하지 않는 경우 일반적인 예외처럼 처리되어 태스크가 오류 상태로 전환됩니다. 다른 예외가 있으면 태스크가 오류 상태로 전환됩니다. 속성에서 완료된 작업의 Status 상태를 가져올 수 있습니다.

취소가 요청된 후에도 작업이 일부 항목을 계속 처리할 수 있습니다.

참고하십시오