enumerator 모드 를 사용 하여 비동기 작업 을 간소화 하 는 상세 한 설명 을 분석 합 니 다.

동기 코드 먼저 보기:public int SumPageSizes(IListuris){    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 로 돌아 가 고 모두 다운로드 가 끝났다 고 볼 수 있 습 니 다.그래서 최종 결과 로 돌아 가 는 거 야.
image
 
imageasync 와 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;}

좋은 웹페이지 즐겨찾기