다음을 통해 공유


작업 취소

System.Threading.Tasks.TaskSystem.Threading.Tasks.Task<TResult> 클래스는 .NET Framework 4에 새로 도입된 취소 토큰을 사용한 취소 기능을 지원합니다. 자세한 내용은 취소를 참조하십시오. 작업 클래스에서 작업을 취소하려면 취소 가능한 작업을 나타내는 사용자 대리자와 취소를 요청한 코드 간의 협조가 필요합니다. 작업을 성공적으로 취소하려면 요청하는 코드에서는 CancellationTokenSource.Cancel 메서드를 호출해야 하고 사용자 대리자에서는 작업을 적시에 종료해야 합니다. 다음 방법 중 하나를 사용하여 작업을 종료할 수 있습니다.

  • 단순히 대리자에서 반환합니다. 대부분의 경우에는 이 방법으로 충분하지만 이 방법으로 "취소된" 작업 인스턴스는 Canceled 상태가 아니라 RanToCompletion 상태로 전환됩니다.

  • OperationCanceledException을 throw하고 취소가 요청된 토큰을 전달합니다. 이렇게 하려면 ThrowIfCancellationRequested 메서드를 사용하는 것이 좋습니다. 이 방법으로 취소된 작업은 Canceled 상태로 전환되므로 호출 코드에서는 이 상태를 통해 작업이 취소 요청에 응답했음을 확인할 수 있습니다.

다음 예제에서는 예외를 throw하는 작업 취소의 기본적인 패턴을 보여 줍니다. 토큰은 사용자 대리자와 작업 인스턴스 자체에 전달됩니다.

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
        End Try

        Console.ReadKey()
    End Sub
End Module
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {

        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // 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 StartNew.

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
                Console.WriteLine(e.Message + " " + v.Message);
        }

        Console.ReadKey();
    }
}

자세한 예제는 방법: 작업 및 해당 자식 취소를 참조하십시오.

작업 인스턴스는 사용자 코드에서 throw된 OperationCanceledException이 관찰될 경우 예외의 토큰을 관련 토큰, 즉 해당 작업을 만든 API에 전달된 토큰과 비교합니다. 두 토큰이 동일하고 토큰의 IsCancellationRequested 속성이 true를 반환하면 해당 작업은 이를 취소 승인으로 해석하고 Canceled 상태로 전환됩니다. Wait 또는 WaitAll 메서드를 사용하여 작업이 완료될 때까지 대기하지 않는 경우 해당 작업은 단순히 상태를 Canceled로 설정합니다.

Canceled 상태로 전환되는 작업에서 대기 중인 경우에는 TaskCanceledException이 AggregateException에 래핑된 상태로 생성되어 throw됩니다. 이 예외는 오류가 아니라 성공적인 취소를 나타냅니다. 따라서 작업의 Exception 속성은 null을 반환합니다.

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

취소를 요청한 후에도 작업에서 일부 항목의 처리를 계속 진행할 수 있습니다.

참고 항목

작업

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

개념

취소