1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Http;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8.  
  9. namespace Test
  10. {
  11. enum CoordinationStatus
  12. {
  13. AllDone,
  14. Cancel,
  15. Timeout
  16. }
  17. class AsyncCoordinator
  18. {
  19. private int statusReported = ;
  20. private int op_count = ;
  21.  
  22. private Action<CoordinationStatus> callback;
  23. private Timer timer;
  24.  
  25. public void AboutToBegin(int num = )
  26. {
  27. Interlocked.Add(ref op_count, num);
  28. }
  29.  
  30. public void JustToEnd()
  31. {
  32. if (Interlocked.Decrement(ref op_count) == )
  33. {
  34. ReportStatus(CoordinationStatus.AllDone);
  35. }
  36. }
  37.  
  38. public void AllBegun(Action<CoordinationStatus> callback, int timeout = Timeout.Infinite)
  39. {
  40. this.callback = callback;
  41. if (timeout != Timeout.Infinite)
  42. {
  43. timer = new Timer(Expired, null, timeout, Timeout.Infinite);
  44. }
  45. JustToEnd();
  46. }
  47.  
  48. private void Expired(object obj)
  49. {
  50. ReportStatus(CoordinationStatus.Cancel);
  51. }
  52. public void Cancel()
  53. {
  54. ReportStatus(CoordinationStatus.Cancel);
  55. }
  56. private void ReportStatus(CoordinationStatus status)
  57. {
  58. if (Interlocked.Exchange(ref statusReported, ) == )
  59. {
  60. callback(status);
  61. }
  62. }
  63.  
  64. }
  65.  
  66. class MultiWebRequests
  67. {
  68. private AsyncCoordinator coordinator = new AsyncCoordinator();
  69.  
  70. private Dictionary<string, object> servers = new Dictionary<string, object>(){
  71. {"http://www.baidu.com",null},
  72. {"http://www.sina.com",null},
  73. {"http://www.qq.com",null},
  74. };
  75.  
  76. public MultiWebRequests()
  77. {
  78.  
  79. var http = new HttpClient();
  80. foreach (var url in servers.Keys)
  81. {
  82. //发送了一个请求
  83. coordinator.AboutToBegin();
  84. http.GetByteArrayAsync(url).ContinueWith(task => GetResult(url, task));
  85. }
  86. //所有请求发送完毕
  87. coordinator.AllBegun(AllDone, Timeout.Infinite);
  88. }
  89.  
  90. private void GetResult(string server, Task<byte[]> task)
  91. {
  92. object res;
  93. if (task.Exception != null)
  94. {
  95. res = task.Exception.InnerExceptions;
  96. }
  97. else
  98. {
  99. res = task.Result.Length;
  100. }
  101. servers[server] = res;
  102. //完成了一个请求
  103. coordinator.JustToEnd();
  104. }
  105.  
  106. public void Cancel()
  107. {
  108. coordinator.Cancel();
  109. }
  110.  
  111. private void AllDone(CoordinationStatus status)
  112. {
  113. switch (status)
  114. {
  115. case CoordinationStatus.AllDone:
  116. Console.WriteLine("allDone: ");
  117.  
  118. foreach (var item in servers)
  119. {
  120. Console.Write(item.Key);
  121. object val = item.Value;
  122. if (val is Exception)
  123. {
  124. Console.WriteLine("Exception: {0}",val.GetType().Name);
  125. }
  126. else
  127. {
  128. Console.WriteLine("returned {0:N0} bytes",val);
  129. }
  130. }
  131. break;
  132. case CoordinationStatus.Cancel:
  133. break;
  134. case CoordinationStatus.Timeout:
  135. break;
  136. default:
  137. break;
  138. }
  139. }
  140. }
  141. }

基元用户模式构造--互锁构造 Interlocked 实现的异步web请求实例的更多相关文章

  1. C#多线程编程(6)--线程安全2 互锁构造Interlocked

    在线程安全1中,我介绍了线程同步的意义和一种实现线程同步的方法:volatile.volatile关键字属于原子操作的一种,若对一个关键字使用volatile,很多时候会显得很"浪费&quo ...

  2. 【C#】C#线程_基元线程的同步构造

    目录结构: contents structure [+] 简介 为什么需要使用线程同步 线程同步的缺点 基元线程同步 什么是基元线程 基元用户模式构造和内核模式构造的比较 用户模式构造 易变构造(Vo ...

  3. 【C#进阶系列】28 基元线程同步构造

    多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...

  4. Clr Via C#读书笔记----基元线程同步构造

    线程文章:http://www.cnblogs.com/edisonchou/p/4848131.html 重点在于多个线程同时访问,保持线程的同步. 线程同步的问题: 1,线程同步比较繁琐,而且容易 ...

  5. C#异步编程(二)用户模式线程同步

    基元线程同步构造 多个线程同时访问共享数据时,线程同步能防止数据损坏.不需要线程同步是最理想的情况,因为线程同步存在许多问题. 第一个问题就是它比较繁琐,而且很容易写错. 第二个问题是,他们会损害性能 ...

  6. [.net]基元线程同步构造

    /* 基元线程同步构造 用户模式构造: 易变构造(Volatile Construct) 互锁构造(Interlocked Construct):自旋锁(Spinlock) 乐观锁(Optimisti ...

  7. CLR via C# I/O基元线程同步构造

    1. 分为用户模式构造和内核模式构造 2. 用户模式构造 a.易失构造 在一个简单数据类型的变量上执行原子性读或写操作 VolaileWrite 强制address中的值在调用时写入,除此之外,按照源 ...

  8. .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)

    本随笔续接:.NET 同步与异步之锁(ReaderWriterLockSlim)(八) 之前的随笔已经说过.加锁虽然能很好的解决竞争条件,但也带来了负面影响:性能方面的负面影响.那有没有更好的解决方案 ...

  9. 基元线程同步构造之 Mutes(互斥体)

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)). 互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section). 因 ...

随机推荐

  1. springboot 入门

    使用maven构建project项目, 配置aliyun仓库, 不赘述 springboot 版本需要: jdk1.7+, maven3.2+ , gradle2.9+ 配置文件 引入父包, 放在&l ...

  2. postgresql逻辑结构--表(二)

    一.创建表 语法: create table table_name( col01_name data_type, col02_name data_type, col03_name data_type, ...

  3. IDA动态调试so文件出现SIGILL

    用ida6.6 调试android的so文件时经常会报SIGILL的错误,意思是指令非法.而且这种错误基本都是发生在系统函数内部,像我遇到过的mmap,fopen,fgets等等.在这些函数内部如果用 ...

  4. git remote: HTTP Basic: Access denied 错误解决办法

    问题描述: git push 报 HTTP Basic: Access denied 错误 原因:本地git配置的用户名.密码与gitlabs上注册的用户名.密码不一致. 解决方案: 1. 如果账号密 ...

  5. 浅析libuv源码-获取精确时间

    在Timer模块中有提到,libuv控制着延迟事件的触发,那么必须想办法精确控制时间. 如果是JS,获取当前时间可以直接通过Date.now()得到一个时间戳,然后将两段时间戳相减得到时间差.一般情况 ...

  6. 用Collectors对List去重

    在学习本篇之前,最好对java8新特性有一定的了解.可以参考:Java8新特性--流(Stream) 场景:有一个实体的List集合,需要根据实体中的某个字段对List去重 要想去重,可以考虑使用Tr ...

  7. .net开源项目整理

    整理一些平时收藏和应用的开源代码,方便自己学习和查阅 1.应用 nopcommerce,开源电商网站,开发环境asp.net mvc(未支持.net core),使用技术(autofac,ef,页面插 ...

  8. Visual studio 2017 Installer 打包.netframework

    前几步和网上其他教程一样的.主要是把.net framework 打包进安装程序里,如果选的是“从与我的应用程序相同的位置下载系统必备组件”,会提示 ERROR: 要在“系统必备”对话框中启用“从与我 ...

  9. Java基础——collection接口

    一.Collection接口的定义 public interfaceCollection<E>extends iterable<E>  从接口的定义中可以发现,此接口使用了泛型 ...

  10. @ContextConfiguration的意思

    @ContextConfiguration的意思 @ContextConfiguration这个注解通常与@RunWith(SpringJUnit4ClassRunner.class)联合使用用来测试 ...