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请求实例的更多相关文章

  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. Python模块: 命令行解析optionparser

    Python 有两个内建的模块用于处理命令行参数:一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数:另一个是 optparse,它功能强大,而 ...

  2. MySQL进程-状态等参数详解

    查看连接 mysql -uroot -p123456 -e "show processlist;" 查看正在执行的sql语句 mysql -uroot -p123456 -e &q ...

  3. Dev-FAT-UAT-PRO

    DEV Development environment FAT Feature Acceptance Test environment UAT User Acceptance Test environ ...

  4. iOS开源项目周报0420

    由OpenDigg 出品的iOS开源项目周报第十七期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. YetAno ...

  5. OpenDigg iOS开源项目月报201704

    由OpenDigg 出品的iOS开源项目月报第一期来啦.我们的iOS开源月报集合了OpenDigg一个月来新收录的优质的iOS开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. Transi ...

  6. Microsoft Office MIME Types

    经常需要查找Microsoft Office MIME Types,终于在MSDN网上找到,摘录如下,以备查阅与参考:http://blogs.msdn.com/b/vsofficedeveloper ...

  7. WPF备忘录(6)WPF实现打印功能

    在WPF 中可以通过PrintDialog 类方便的实现应用程序打印功能,本文将使用一个简单实例进行演示.首先在VS中编辑一个图形(如下图所示). 将需要打印的内容放入同一个<Canvas> ...

  8. 卸载阿里云自带svn

  9. js-数字、字符串、布尔值的转换方式

    来自JavaScript秘密花园 1.转换为字符串 '' + 10 === '10'; // true 将一个值加上空字符串可以轻松转换为字符串类型. 2.字符串转换为数字 +'010' === 10 ...

  10. 图片圆角显示与手机版文章页面CSS布局

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...