동기 코드 먼저 보기:public int SumPageSizes(IList
uris){ int total = 0; foreach (var uri in uris) { statusText.Text = string.Format("Found {0} bytes ...", total); var data = new WebClient().DownloadData(uri); total += data.Length; } statusText.Text = string.Format("Found {0} bytes total", total); return total; } 이 코드 는 비교적 간단 합 니 다.동기 화 방식 으로 Uri 의 Data 를 하나씩 가 져 온 다음 에 통 계 를 합 니 다.비동기 식 통 계 를 사용 하려 면 어떻게 계산 해 야 합 니까?나 는 이전에 추악 한 코드 를 대략 다음 과 같이 보 여 준 적 이 있다. WebClient webClient = new WebClient(); webClient.DownloadDataCompleted += (s, e) => { // A 상 대 를 이용 하여 일 을 하 다. WebClient webClient2 = new WebClient(); webClient2.DownloadDataCompleted += (s2, e2) => { //B 상 대 를 이용 하여 일 을 하 다. // 재 귀적 으로 DownloadDataAsync 로 갑 니 다. }; webClient 2.DownloadDataAsync(new Uri("B 의 주소"); }; webClient.DownloadDataAsync(new Uri("A 의 주소");물론 주소 가 두 개 밖 에 없다 는 것 이 확실 하 다 면 이런 방법 은 안 될 것 이 없다.만약 여러 개의 주소 가 있다 면,반드시 재 귀적 으로 호출 해 야 한다.Enumerator 를 사용 하여 비동기 동작 을 간소화 하 는 방법:Public void SumPageSizesAsync(IListuris){ SumPageSizesAsyncHelper(uris.GetEnumerator(), 0); } private void SumPageSizesAsyncHelper(IEnumerator enumerator, int total) { if (enumerator.MoveNext()) { statusText.Text = string.Format("Found {0} bytes ...", total); var client = new WebClient(); client.DownloadDataCompleted += (sender, e) => { SumPageSizesAsyncHelper(enumerator, total + e.Result.Length); }; client.DownloadDataAsync(enumerator.Current); } else { statusText.Text = string.Format("Found {0} bytes total", total); enumerator.Dispose(); } } SumPageSizesAsyncHelper 를 통 해 비동기 호출 A->비동기 호출 B->비동기 호출 C..방식 을 실현 할 수 있 습 니 다.먼저 왜 가능 한 지 설명 하 십시오.만약 에 uris 에 A,B,C.SumPageSizes AsyncHelper(uris.GetEnumerator(),0)가 있다 고 가정 하 십시오.
방법 은 먼저 A 를 호출 합 니 다.A 뒤에 B 가 있 기 때문에 enumerator.MoveNext()는 True 로 돌아 갑 니 다.이 어 DownloadDataComplete 이벤트 가 끝 난 후에 B 를 호출 합 니 다.마찬가지 로 B 뒤에 C 가 있 기 때문에 enumerator.MoveNext()는 True 로 계속 돌아 갑 니 다.이 어 DownloadDataComplete 이벤트 후에 C 를 호출 합 니 다.호출 C 가 끝 난 후 C 뒤에 없 기 때문에 enumerator.MoveNext()는 False 로 돌아 가 고 모두 다운로드 가 끝났다 고 볼 수 있 습 니 다.그래서 최종 결과 로 돌아 가 는 거 야.
async 와 await 를 사용 하여 이 루어 진다 면 코드 는 다음 과 같 습 니 다:Public async TaskSumPageSizes Async 2(IListuris){ int total = 0; Char charText = 'A'; foreach (var uri in uris) { var data = await new WebClient().DownloadDataTaskAsync(uri); total += data.Length; Console.WriteLine("Thread Id:{0}:{1}의 주 소 를 호출 합 니 다.Found{2}bytes...{3}", Thread.CurrentThread.ManagedThreadId, charText, total, DateTime.Now); charText = Convert.ToChar(charText + 1); } Console.WriteLine("Thread Id:{0}:모두 완료,Found{1}bytes total{2}", Thread.CurrentThread.ManagedThreadId, total, DateTime.Now); return total;}