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 }
时间: 2024-10-10 06:55:55