当前位置:  编程技术>.net/c#/asp.net

解析使用enumerator模式简化异步操作的详解

    来源: 互联网  发布时间:2014-10-20

    本文导语:  先看一段同步代码: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; ...

先看一段同步代码:

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。
     };
     webClient2.DownloadDataAsync(new Uri("B 的地址"));
 };
 webClient.DownloadDataAsync(new Uri("A 的地址"));

当然如果你确定只有两个地址的话,这种方法未尝不可。如果有多个地址的话,则必须递归的调用了。

如何使用Enumerator来简化异步操作:

public void SumPageSizesAsync(IList uris) {
    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.

SumPageSizesAsyncHelper(uris.GetEnumerator(), 0);

方法先调用A,因为A后面还有B,所以enumerator.MoveNext()返回True,
接着在DownloadDataCompleted事件结束后,调用B,同样,因为B后面还有C,
所以enumerator.MoveNext() 继续返回True,接着在DownloadDataCompleted事件后调用C。
在调用C结束后,因为C后面没有了,所以enumerator.MoveNext() 返回False,
也可以认为全部都下载完毕了。所以返回最终的结果。

 




如果使用async 和await来实现的话,代码如下:

public async Task SumPageSizesAsync2(IList uris)
{
    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;
}


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 解析取模运算% 和位与运算& 之间的关系详解
  • 解析Linux系统中JVM内存2GB上限的详解
  • ThinkPHP3.1新特性之内容解析输出详解
  • 解析c++中的默认operator=操作的详解
  • 解析C#彩色图像灰度化算法的实现代码详解
  • 解析C#中@符号的几种使用方法详解
  • 解析后台进程对Android性能影响的详解
  • 解析Android开发优化之:对界面UI的优化详解(三)
  • 解析在内部循环中Continue外部循环的使用详解
  • 解析Linux系统中JVM内存2GB上限的详解 iis7站长之家
  • 解析Android开发优化之:对界面UI的优化详解(二)
  • 解析JAVA深度克隆与浅度克隆的区别详解
  • 解析jdbc处理oracle的clob字段的详解
  • 解析C#中的装箱与拆箱的详解
  • 解析Runtime中shutdown hook的使用详解
  • DHCP:解析开发板上动态获取ip的2种实现方法详解
  • java Class文件内部结构解析过程详解
  • 深入多线程之:解析线程的交会(Thread Rendezvous)详解
  • 解析为何要关闭数据库连接,可不可以不关闭的问题详解
  • 解析c++中参数对象与局部对象的析构顺序的详解
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • 请教redhat9下什么命令执行arp解析和逆向arp解析
  • 使用libpcap读取tcpdump抓取的文件并解析c代码实例
  • 如何用libxml2 默认解析器解析HTML文件
  • 基于Python的Html/xml解析库Beautiful Soup 4.2.1发布
  • linux能否成为动态域名解析客户端的动态域名解析服务器?
  • html中<radio>单选按钮控件标签用法解析及如何设置默认选中
  • 配置DNS服务器后,服务器可解析,客户端不能解析。求解
  • Python下Html/xml解析库Beautiful Soup快速入门教程
  • 为什么我在使用nslookup命令的时候,正向解析(域名-》ip)没有问题,反向解析(ip-》域名)怎么查不到呢?
  • 基于Python的html解析库:pyquery最新版主页及pyquery下载


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3