基元用户模式构造--互锁构造 Interlocked 实现的异步web请求实例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace Test
{
enum CoordinationStatus
{
AllDone,
Cancel,
Timeout
}
class AsyncCoordinator
{
private int statusReported = ;
private int op_count = ; private Action<CoordinationStatus> callback;
private Timer timer; public void AboutToBegin(int num = )
{
Interlocked.Add(ref op_count, num);
} public void JustToEnd()
{
if (Interlocked.Decrement(ref op_count) == )
{
ReportStatus(CoordinationStatus.AllDone);
}
} public void AllBegun(Action<CoordinationStatus> callback, int timeout = Timeout.Infinite)
{
this.callback = callback;
if (timeout != Timeout.Infinite)
{
timer = new Timer(Expired, null, timeout, Timeout.Infinite);
}
JustToEnd();
} private void Expired(object obj)
{
ReportStatus(CoordinationStatus.Cancel);
}
public void Cancel()
{
ReportStatus(CoordinationStatus.Cancel);
}
private void ReportStatus(CoordinationStatus status)
{
if (Interlocked.Exchange(ref statusReported, ) == )
{
callback(status);
}
} } class MultiWebRequests
{
private AsyncCoordinator coordinator = new AsyncCoordinator(); private Dictionary<string, object> servers = new Dictionary<string, object>(){
{"http://www.baidu.com",null},
{"http://www.sina.com",null},
{"http://www.qq.com",null},
}; public MultiWebRequests()
{ var http = new HttpClient();
foreach (var url in servers.Keys)
{
//发送了一个请求
coordinator.AboutToBegin();
http.GetByteArrayAsync(url).ContinueWith(task => GetResult(url, task));
}
//所有请求发送完毕
coordinator.AllBegun(AllDone, Timeout.Infinite);
} private void GetResult(string server, Task<byte[]> task)
{
object res;
if (task.Exception != null)
{
res = task.Exception.InnerExceptions;
}
else
{
res = task.Result.Length;
}
servers[server] = res;
//完成了一个请求
coordinator.JustToEnd();
} public void Cancel()
{
coordinator.Cancel();
} private void AllDone(CoordinationStatus status)
{
switch (status)
{
case CoordinationStatus.AllDone:
Console.WriteLine("allDone: "); foreach (var item in servers)
{
Console.Write(item.Key);
object val = item.Value;
if (val is Exception)
{
Console.WriteLine("Exception: {0}",val.GetType().Name);
}
else
{
Console.WriteLine("returned {0:N0} bytes",val);
}
}
break;
case CoordinationStatus.Cancel:
break;
case CoordinationStatus.Timeout:
break;
default:
break;
}
}
}
}
基元用户模式构造--互锁构造 Interlocked 实现的异步web请求实例的更多相关文章
- C#多线程编程(6)--线程安全2 互锁构造Interlocked
在线程安全1中,我介绍了线程同步的意义和一种实现线程同步的方法:volatile.volatile关键字属于原子操作的一种,若对一个关键字使用volatile,很多时候会显得很"浪费&quo ...
- 【C#】C#线程_基元线程的同步构造
目录结构: contents structure [+] 简介 为什么需要使用线程同步 线程同步的缺点 基元线程同步 什么是基元线程 基元用户模式构造和内核模式构造的比较 用户模式构造 易变构造(Vo ...
- 【C#进阶系列】28 基元线程同步构造
多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...
- Clr Via C#读书笔记----基元线程同步构造
线程文章:http://www.cnblogs.com/edisonchou/p/4848131.html 重点在于多个线程同时访问,保持线程的同步. 线程同步的问题: 1,线程同步比较繁琐,而且容易 ...
- C#异步编程(二)用户模式线程同步
基元线程同步构造 多个线程同时访问共享数据时,线程同步能防止数据损坏.不需要线程同步是最理想的情况,因为线程同步存在许多问题. 第一个问题就是它比较繁琐,而且很容易写错. 第二个问题是,他们会损害性能 ...
- [.net]基元线程同步构造
/* 基元线程同步构造 用户模式构造: 易变构造(Volatile Construct) 互锁构造(Interlocked Construct):自旋锁(Spinlock) 乐观锁(Optimisti ...
- CLR via C# I/O基元线程同步构造
1. 分为用户模式构造和内核模式构造 2. 用户模式构造 a.易失构造 在一个简单数据类型的变量上执行原子性读或写操作 VolaileWrite 强制address中的值在调用时写入,除此之外,按照源 ...
- .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
本随笔续接:.NET 同步与异步之锁(ReaderWriterLockSlim)(八) 之前的随笔已经说过.加锁虽然能很好的解决竞争条件,但也带来了负面影响:性能方面的负面影响.那有没有更好的解决方案 ...
- 基元线程同步构造之 Mutes(互斥体)
互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)). 互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section). 因 ...
随机推荐
- Python学习--14 序列化
把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等. pickle ...
- Java NIO系列教程(九) ServerSocketChannel
Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样.ServerSocketChannel类在 jav ...
- Redis Cluster高可用集群在线迁移操作记录
之前介绍了redis cluster的结构及高可用集群部署过程,今天这里简单说下redis集群的迁移.由于之前的redis cluster集群环境部署的服务器性能有限,需要迁移到高配置的服务器上.考虑 ...
- Python后端相关技术/工具栈
编辑器 最常见: vim / SublimeText2 / PyCharm Vim有兴趣可以看看 k-vim 适合Python/Golang开发 本地环境 pip/easy_install 包管理 v ...
- Android性能测试--垃圾回收频次统计的作用
频繁的垃圾回收有可能暗示着内存泄露,在我手机统计数据,每次垃圾回收会占据100ms左右,这对内存和事件响应要求严格的程序(游戏等)来讲是可观的性能损耗.
- git第六节---git 远程仓库
远程分支类似于本地分支,是指向远程仓库中的文件的指针. 1.远程分支抓取 @git fetch origin dev :拉取远程dev内容 fetch不会对本地仓库内容进行更新,只更新远端commit ...
- javascript 易错点、难点笔记
本文主要记录在学习过程中遇到的JavaScript难点或者容易疏忽的细节,也方便自己日后翻阅学习. 1.arr.length === + arr.length arr.length === + arr ...
- Java并发系列[10]----ThreadPoolExecutor源码分析
在日常的开发调试中,我们经常会直接new一个Thread对象来执行某个任务.这种方式在任务数较少的情况下比较简单实用,但是在并发量较大的场景中却有着致命的缺陷.例如在访问量巨大的网站中,如果每个请求都 ...
- 用canvas画弧形进度条
function toCanvas(id ,progress){ //canvas进度条 var canvas = document.getElementById(id), ctx = canvas. ...
- JS DOM 操作 项目总结 【超链接】【数列】【span】
超链接 每次定义链接样式时务必确认定义的顺序,link--visited--hover-active,也就是我们常说到的LoVe HAte原则(大写字母就是它们的首字母). “爱恨原则”(Lo ...