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 = 0;
20 private int op_count = 1;
21
22 private Action<CoordinationStatus> callback;
23 private Timer timer;
24
25 public void AboutToBegin(int num = 1)
26 {
27 Interlocked.Add(ref op_count, num);
28 }
29
30 public void JustToEnd()
31 {
32 if (Interlocked.Decrement(ref op_count) == 0)
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, 1) == 0)
59 {
60 callback(status);
61 }
62 }
63
64
65
66 }
67
68 class MultiWebRequests
69 {
70 private AsyncCoordinator coordinator = new AsyncCoordinator();
71
72 private Dictionary<string, object> servers = new Dictionary<string, object>(){
73 {"http://www.baidu.com",null},
74 {"http://www.sina.com",null},
75 {"http://www.qq.com",null},
76 };
77
78 public MultiWebRequests()
79 {
80
81 var http = new HttpClient();
82 foreach (var url in servers.Keys)
83 {
84 //发送了一个请求
85 coordinator.AboutToBegin(1);
86 http.GetByteArrayAsync(url).ContinueWith(task => GetResult(url, task));
87 }
88 //所有请求发送完毕
89 coordinator.AllBegun(AllDone, Timeout.Infinite);
90 }
91
92 private void GetResult(string server, Task<byte[]> task)
93 {
94 object res;
95 if (task.Exception != null)
96 {
97 res = task.Exception.InnerExceptions;
98 }
99 else
100 {
101 res = task.Result.Length;
102 }
103 servers[server] = res;
104 //完成了一个请求
105 coordinator.JustToEnd();
106 }
107
108 public void Cancel()
109 {
110 coordinator.Cancel();
111 }
112
113 private void AllDone(CoordinationStatus status)
114 {
115 switch (status)
116 {
117 case CoordinationStatus.AllDone:
118 Console.WriteLine("allDone: ");
119
120 foreach (var item in servers)
121 {
122 Console.Write(item.Key);
123 object val = item.Value;
124 if (val is Exception)
125 {
126 Console.WriteLine("Exception: {0}",val.GetType().Name);
127 }
128 else
129 {
130 Console.WriteLine("returned {0:N0} bytes",val);
131 }
132 }
133 break;
134 case CoordinationStatus.Cancel:
135 break;
136 case CoordinationStatus.Timeout:
137 break;
138 default:
139 break;
140 }
141 }
142 }
143 }