Task 수행 중에 Wait 메서드를 호출하거나 Result 속성을 살펴보게 되면 거의 항상 스레드 풀 내에 새로운 스레드가 생기게 되어 리소스를 많이 사용하게 되고 성능에 좋지 않은 영향을 미치게 된다. Wait 메서드나 Result 속성보다 Task가 언제 수행 완료하였는지를 확인할 수 있는 좋은 방법이 있는데, ContinueWith 메소드를 이용해 Task가 완료되었을 때 다른 Task를 수행하게 하는 방법이다.
- CancellationTokenSource와 Task를 생성
1: CancellationTokenSource cts = new CancellationTokenSource();
2: Task<Int32> t = Task.Run<Int32>(() => Sum(cts.Token, 10000), cts.Token);
- Task 성공, 예외 발생, 취소 후 수행할 Task를 등록
1: // 작업이 성공했을 경우 실행
2: t.ContinueWith(task => Console.Write("The sum is: " + task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
3: // 작업에 예외가 발생했을 경우 실행
4: t.ContinueWith(task => {
5: foreach (var e in task.Exception.InnerExceptions)
6: {
7: if (e is OperationCanceledException) Console.WriteLine("Sum was canceled");
8: else Console.WriteLine("Sum threw: " + task.Exception);
9: }
10: }, TaskContinuationOptions.OnlyOnFaulted);
11: // 작업이 취소 되었을 경우 실행
12: t.ContinueWith(task => Console.Write("Sum was canceld"), TaskContinuationOptions.OnlyOnCanceled);
1: cts.Cancel();
1: private static void TaskCancelSample()
2: {
3: CancellationTokenSource cts = new CancellationTokenSource();
4: Task<Int32> t = Task.Run<Int32>(() => Sum(cts.Token, 10000), cts.Token);
5:
6: // 작업이 성공했을 경우 실행
7: t.ContinueWith(task => Console.Write("The sum is: " + task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
8: // 작업에 예외가 발생했을 경우 실행
9: t.ContinueWith(task => {
10: foreach (var e in task.Exception.InnerExceptions)
11: {
12: if (e is OperationCanceledException) Console.WriteLine("Sum was canceled");
13: else Console.WriteLine("Sum threw: " + task.Exception);
14: }
15: }, TaskContinuationOptions.OnlyOnFaulted);
16: // 작업이 취소 되었을 경우 실행
17: t.ContinueWith(task => Console.Write("Sum was canceld"), TaskContinuationOptions.OnlyOnCanceled);
18:
19: //cts.Cancel();
20: }
21:
22: private static Int32 Sum(CancellationToken ct, Int32 n)
23: {
24: Int32 sum = 0;
25: for (; n > 0; n--)
26: {
27: // ct가 참조하는 CancellationTokenSource 객체의 Cancel 메서드가 호출된 경우
28: // OperationCancelException을 던진다.
29: ct.ThrowIfCancellationRequested();
30:
31: checked { sum += n; }
32: }
33:
34: return sum;
35: }
댓글
댓글 쓰기