■ CancellationTokenSource 클래스의 CancelAfter 메소드를 사용해 타임아웃시 작업을 취소하는 방법을 보여준다.
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 취소 토큰 소스 /// </summary> private static CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); /// <summary> /// HTTP 클라이언트 /// </summary> private static HttpClient _httpClient = new HttpClient { MaxResponseContentBufferSize = 1000000L }; /// <summary> /// URL 리스트 /// </summary> private static List<string> _urlList = new List<string> { "https://docs.microsoft.com", "https://docs.microsoft.com/aspnet/core", "https://docs.microsoft.com/azure", "https://docs.microsoft.com/azure/devops", "https://docs.microsoft.com/dotnet", "https://docs.microsoft.com/dynamics365", "https://docs.microsoft.com/education", "https://docs.microsoft.com/enterprise-mobility-security", "https://docs.microsoft.com/gaming", "https://docs.microsoft.com/graph", "https://docs.microsoft.com/microsoft-365", "https://docs.microsoft.com/office", "https://docs.microsoft.com/powershell", "https://docs.microsoft.com/sql", "https://docs.microsoft.com/surface", "https://docs.microsoft.com/system-center", "https://docs.microsoft.com/visualstudio", "https://docs.microsoft.com/windows", "https://docs.microsoft.com/xamarin" }; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 컨텐트 길이 구하기 (비동기) - GetContentLengthAsync(httpClient, url, cancellationToken) /// <summary> /// 컨텐트 길이 구하기 (비동기) /// </summary> /// <param name="httpClient">HTTP 클라이언트</param> /// <param name="url">URL</param> /// <param name="cancellationToken">취소 토큰</param> /// <returns>컨텐트 길이 태스크</returns> private static async Task<int> GetContentLengthAsync(HttpClient httpClient, string url, CancellationToken cancellationToken) { HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(url, cancellationToken); byte[] contentByteArray = await httpResponseMessage.Content.ReadAsByteArrayAsync(cancellationToken); Console.WriteLine($"{url, -60} {contentByteArray.Length, 10:#,#}"); return contentByteArray.Length; } #endregion #region 전체 컨텐트 길이 출력하기 (비동기) - PrintTotalContentLengthAsync() /// <summary> /// 전체 컨텐트 길이 출력하기 (비동기) /// </summary> /// <returns>태스크</returns> private static async Task PrintTotalContentLengthAsync() { Stopwatch watch = Stopwatch.StartNew(); int totalLength = 0; foreach(string url in _urlList) { int contentLength = await GetContentLengthAsync(_httpClient, url, _cancellationTokenSource.Token); totalLength += contentLength; } watch.Stop(); Console.WriteLine($"전체 바이트 : {totalLength:#,#}"); Console.WriteLine($"경과 시간 : {watch.Elapsed}"); } #endregion #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> /// <returns>태스크</returns> private static async Task Main() { Console.WriteLine("프로그램을 시작합니다."); try { _cancellationTokenSource.CancelAfter(3000); await PrintTotalContentLengthAsync(); } catch(TaskCanceledException) { Console.WriteLine("태스크가 취소되었습니다 : 타임아웃"); } finally { _cancellationTokenSource.Dispose(); } Console.WriteLine("프로그램을 종료합니다."); } #endregion } } |