방법: 취소 요청에 대한 콜백 등록
토큰을 만든 개체에 대해 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 메서드가 아무 작업도 수행하지 않기 때문에 이 메서드를 항상 안전하게 호출할 수 있습니다.