다음을 통해 공유


방법: 취소 요청에 대한 콜백 등록

토큰을 만든 개체에 대해 Cancel을 호출한 결과로 IsCancellationRequested 속성이 true가 될 때 호출될 대리자를 등록하는 방법을 보여 줍니다. 이 방법을 사용하여 기본적으로 통합 취소 프레임워크를 지원하지 않는 비동기 작업을 취소하고 비동기 작업이 완료되기를 기다리고 있을 수 있는 메서드의 차단을 해제합니다.

참고참고

"내 코드만"을 사용하는 경우 Visual Studio에서는 예외를 throw하는 줄에서 실행을 중단하고 예외가 사용자 코드를 통해 처리되지 않았음을 알리는 오류 메시지를 표시할 수 있습니다. 이는 크게 심각한 오류는 아닙니다.F5 키를 눌러 중단된 지점부터 실행을 계속하고 아래 예제에 나와 있는 것과 같은 예외 처리 동작을 확인할 수 있습니다.맨 처음 오류 지점에서 Visual Studio가 실행을 중단하지 않도록 하려면 도구, 옵션, 디버깅, 일반을 차례로 선택하고 "내 코드만" 확인란의 선택을 취소하기만 하면 됩니다.

예제

다음 예제에서는 CancelAsync 메서드가 취소 토큰을 통해 취소가 요청될 때 호출될 메서드로 등록됩니다.



Class CancelWithCallback


    Shared Sub Main()

        Dim cts As New CancellationTokenSource()

        ' Start cancelable task.
        Dim t As Task = Task.Factory.StartNew(Sub() DoWork(cts.Token))

        Console.WriteLine("Press 'c' to cancel.")
        Dim ch As Char = Console.ReadKey().KeyChar
        If ch = "c"c Then

            cts.Cancel()
        End If
        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()
    End Sub

    Shared Sub DoWork(ByVal token As CancellationToken)

        Dim wc As New WebClient()

        ' Create an event handler to receive the result.
        AddHandler wc.DownloadStringCompleted, Sub(obj, e)

                                                   ' Checks status of WebClient, not external token
                                                   If e.Cancelled = False Then

                                                       Console.WriteLine(e.Result + "\r\nPress any key.")

                                                   Else
                                                       Console.WriteLine("Download was canceled.")
                                                   End If
                                               End Sub

        token.Register(Sub() wc.CancelAsync())

        Console.WriteLine("Starting request")
        wc.DownloadStringAsync(New Uri("https://www.contoso.com"))
    End Sub
End Class
namespace Cancel3
{
    using System;
    using System.Net;
    using System.Threading;
    using System.Threading.Tasks;

    class CancelWithCallback
    {

        static void Main(string[] args)
        {
            var cts = new CancellationTokenSource();

            // Start cancelable task.
            Task t = Task.Factory.StartNew(() =>
            {
                DoWork(cts.Token);
            });

            Console.WriteLine("Press 'c' to cancel.");
            char ch = Console.ReadKey().KeyChar;
            if (ch == 'c')
            {
                cts.Cancel();
            }
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }

        static void DoWork(CancellationToken token)
        {
            WebClient wc = new WebClient();

            // Create an event handler to receive the result.
            wc.DownloadStringCompleted += (obj, e) =>
            {
                // Checks status of WebClient, not external token
                if (!e.Cancelled)
                {
                    Console.WriteLine(e.Result + "\r\nPress any key.");
                }
                else
                    Console.WriteLine("Download was canceled.");
            };

            // Do not initiate download if the external token
            // has already been canceled.
            if (!token.IsCancellationRequested)
            {
                // Register the callback to a method that can unblock.
                // Dispose of the CancellationTokenRegistration object
                // after the callback has completed.
                using (CancellationTokenRegistration ctr = token.Register(() => wc.CancelAsync()))
                {
                    Console.WriteLine("Starting request");
                    wc.DownloadStringAsync(new Uri("https://www.contoso.com"));
                }
            }
        }
    }
}

콜백이 등록될 때 취소가 이미 요청된 경우 해당 콜백은 계속 호출이 보장됩니다. 이러한 특별한 경우에는 진행 중인 비동기 작업이 없을 경우 CancelAsync 메서드가 아무 작업도 수행하지 않기 때문에 이 메서드를 항상 안전하게 호출할 수 있습니다.

참고 항목

개념

취소