基元用户模式构造--互锁构造 Interlocked 实现的异步web请求实例

 

  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 }

 

posted @ 2017-03-08 00:06  Young汨  阅读(398)  评论(0编辑  收藏  举报