Advertisement
Guest User

Untitled

a guest
Jul 12th, 2013
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Net.Http;
  8. using System.Runtime.Serialization.Json;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12.  
  13. namespace Tests.Service
  14. {
  15.     class ServiceManager : IDisposable
  16.     {
  17.         private const int PAGINATION = 3;
  18.         private const string API_KEY = "..."; //use your custom API key here
  19.         private const string BASE_URL = "http://api.timezonedb.com/?zone={0}&format=json&key={1}";
  20.  
  21.         private DataContractJsonSerializer _serializer = new DataContractJsonSerializer(typeof(TimeModel));
  22.  
  23.         private List<TimeModel> _mainBuffer = new List<TimeModel>(PAGINATION);
  24.         private List<TimeModel> _secondaryBuffer;
  25.  
  26.         internal delegate void OnDownloadsFinishedHandler(object sender, EventArgs e);
  27.         internal event OnDownloadsFinishedHandler OnDownloadsFinished;
  28.  
  29.         private List<HttpClient> clients;
  30.  
  31.         private ServiceManager()
  32.         {
  33.             clients = new List<HttpClient>();
  34.             for (int i = 0; i < TimeZonesCount; i++)
  35.             {
  36.                 clients.Add(new HttpClient());
  37.             }
  38.         }
  39.         void IDisposable.Dispose()
  40.         {
  41.             foreach (var client in clients)
  42.                 client.Dispose();
  43.         }
  44.        
  45.         private void HandleBufferFull(List<TimeModel> localBuffer)
  46.         {
  47.             DoSomethingWithThisBuffer(localBuffer); //save to DB, display to UI, whatever... you're supposed to have an array of PAGINATION size here
  48.             localBuffer.Clear();
  49.         }
  50.         private static Mutex mutex = new Mutex();
  51.  
  52.         internal async Task StartDownloading()
  53.         {
  54.             IEnumerable<Task> tasks =Enumerable.Range(0, TimeZonesCount - 1).Select(index =>
  55.               Task.Run(async () =>
  56.               {
  57.                   var lastBatch = false;
  58.                   if (TimeZonesCount - index - 1 < PAGINATION)
  59.                   {
  60.                       lastBatch = true;
  61.                       _secondaryBuffer = new List<TimeModel>(TimeZonesCount % PAGINATION);
  62.                   }
  63.  
  64.                   List<TimeModel> localBuffer;
  65.                   bool hasMutex = false;
  66.                   if (lastBatch)
  67.                   {
  68.                       localBuffer = _secondaryBuffer;
  69.                   }
  70.                   else
  71.                   {
  72.                       localBuffer = _mainBuffer;
  73.                   }
  74.                   try
  75.                   {
  76.  
  77.                       var query = string.Format(BASE_URL, zones[index], API_KEY);
  78.  
  79.                       var response = await clients[index].GetAsync(query);
  80.                       var json = await response.Content.ReadAsStringAsync();
  81.                       TimeModel model = Deserialize(json);
  82.  
  83.                       hasMutex = mutex.WaitOne();
  84.                       if (!hasMutex)
  85.                           throw new Exception("MutexException");
  86.  
  87.                       localBuffer.Add(model);
  88.                   }
  89.                   catch (ObjectDisposedException ode)
  90.                   {
  91.                       throw;
  92.                   }
  93.                   catch (Exception e)
  94.                   {
  95.                       if (!hasMutex)
  96.                           hasMutex = mutex.WaitOne();
  97.                       TimeModel model = new TimeModel();
  98.                       model.ZoneName = zones[index];
  99.                       model.IsError = true;
  100.                       localBuffer.Add(model);
  101.                   }
  102.                   finally
  103.                   {
  104.  
  105.                       try
  106.                       {
  107.                           if (localBuffer.Count == localBuffer.Capacity && hasMutex)
  108.                           {
  109.                               HandleBufferFull(localBuffer);
  110.                           }
  111.                           if (hasMutex)
  112.                           {
  113.                               mutex.ReleaseMutex();
  114.                           }
  115.                       }
  116.                       catch (Exception finallyException)
  117.                       {
  118.                          
  119.                           throw;
  120.                       }
  121.                   }
  122.                   return 0;
  123.               }));
  124.  
  125.             try
  126.             {
  127.                 await Task.WhenAll(tasks);
  128.                
  129.                 /*
  130.                 foreach(var task in tasks)
  131.                 {
  132.                     await task;
  133.                 }
  134.                 */
  135.                
  136.                 /*
  137.                 foreach(var task in tasks)
  138.                 {
  139.                     if(task.Status != TaskStatus.RanToCompletion)
  140.                     {
  141.                         await task;
  142.                     }
  143.                 }
  144.                 */
  145.                 OnDownloadsFinished(this, new EventArgs());
  146.             }
  147.             catch (Exception e)
  148.             {
  149.                 throw;
  150.             }
  151.         }
  152.         internal TimeModel Deserialize(string json)
  153.         {
  154.             var model = JsonConvert.DeserializeObject<TimeModel>(json);
  155.             return model;
  156.         }
  157.  
  158.         internal int TimeZonesCount
  159.         {
  160.             get
  161.             {
  162.                 return zones.Length;
  163.             }
  164.         }
  165.  
  166.         #region Singleton Impl
  167.         private static ServiceManager _instance;
  168.         internal static ServiceManager Instance
  169.         {
  170.             get
  171.             {
  172.                 if (_instance == null)
  173.                     _instance = new ServiceManager();
  174.  
  175.                 return _instance;
  176.             }
  177.         }
  178.         #endregion
  179.  
  180.         #region Time Zones
  181.         private readonly string[] zones =
  182.         {
  183.             "Europe/Andorra",
  184.             "Asia/Dubai",
  185.             "Asia/Kabul",
  186.             "America/Antigua",
  187.             "America/Anguilla",
  188.             "Europe/Tirane",
  189.             "Asia/Yerevan",
  190.             "Africa/Luanda",
  191.             "Antarctica/McMurdo",
  192.             "Antarctica/South_Pole",
  193.             "Antarctica/Rothera",
  194.             "Antarctica/Palmer",
  195.             "Antarctica/Mawson",
  196.             "Antarctica/Davis",
  197.             "Antarctica/Casey",
  198.             "Antarctica/Vostok",
  199.             "Antarctica/DumontDUrville",
  200.             "Antarctica/Syowa",
  201.             "Antarctica/Macquarie",
  202.             "America/Argentina/Catamarca",
  203.             "America/Argentina/La_Rioja",
  204.             "America/Argentina/San_Juan",
  205.             "America/Argentina/Mendoza",
  206.             "America/Argentina/San_Luis",
  207.             "America/Argentina/Rio_Gallegos",
  208.             "America/Argentina/Ushuaia",
  209.             "America/Argentina/Buenos_Aires",
  210.             "America/Argentina/Cordoba",
  211.             "America/Argentina/Salta",
  212.             "America/Argentina/Jujuy",
  213.             "America/Argentina/Tucuman",
  214.             "Pacific/Pago_Pago",
  215.             "Europe/Vienna",
  216.             "Australia/Lord_Howe",
  217.             "Australia/Hobart",
  218.             "Australia/Currie",
  219.             "Australia/Melbourne",
  220.             "Australia/Sydney",
  221.             "Australia/Broken_Hill",
  222.             "Australia/Brisbane",
  223.             "Australia/Lindeman",
  224.             "Australia/Adelaide",
  225.             "Australia/Darwin",
  226.             "Australia/Perth",
  227.             "Australia/Eucla",
  228.             "America/Aruba",
  229.             "Europe/Mariehamn",
  230.             "Asia/Baku",
  231.             "Europe/Sarajevo",
  232.             "America/Barbados",
  233.             "Asia/Dhaka",
  234.             "Europe/Brussels",
  235.             "Africa/Ouagadougou",
  236.             "Europe/Sofia",
  237.             "Asia/Bahrain",
  238.             "Africa/Bujumbura",
  239.             "Africa/Porto-Novo",
  240.             "America/St_Barthelemy",
  241.             "Atlantic/Bermuda",
  242.             "Asia/Brunei",
  243.             "America/La_Paz",
  244.             "America/Kralendijk",
  245.             "America/Noronha",
  246.             "America/Belem",
  247.             "America/Fortaleza",
  248.             "America/Recife",
  249.             "America/Araguaina",
  250.             "America/Maceio",
  251.             "America/Bahia",
  252.             "America/Sao_Paulo",
  253.             "America/Campo_Grande",
  254.             "America/Cuiaba",
  255.             "America/Santarem",
  256.             "America/Porto_Velho",
  257.             "America/Boa_Vista",
  258.             "America/Manaus",
  259.             "America/Eirunepe",
  260.             "America/Rio_Branco",
  261.             "America/Nassau",
  262.             "Asia/Thimphu",
  263.             "Africa/Gaborone",
  264.             "Europe/Minsk",
  265.             "America/Belize",
  266.             "America/Blanc-Sablon",
  267.             "America/Montreal",
  268.             "America/Toronto",
  269.             "America/Nipigon",
  270.             "America/Thunder_Bay",
  271.             "America/Iqaluit",
  272.             "America/Pangnirtung",
  273.             "America/Resolute",
  274.             "America/Atikokan",
  275.             "America/Rankin_Inlet",
  276.             "America/Winnipeg",
  277.             "America/Rainy_River",
  278.             "America/Regina",
  279.             "America/Swift_Current",
  280.             "America/Edmonton",
  281.             "America/Cambridge_Bay",
  282.             "America/Yellowknife",
  283.             "America/Inuvik",
  284.             "America/Dawson_Creek",
  285.             "America/Vancouver",
  286.             "America/Whitehorse",
  287.             "America/Dawson",
  288.             "America/St_Johns",
  289.             "America/Halifax",
  290.             "America/Glace_Bay",
  291.             "America/Moncton",
  292.             "America/Goose_Bay",
  293.             "Indian/Cocos",
  294.             "Africa/Kinshasa",
  295.             "Africa/Lubumbashi",
  296.             "Africa/Bangui",
  297.             "Africa/Brazzaville",
  298.             "Europe/Zurich",
  299.             "Africa/Abidjan",
  300.             "Pacific/Rarotonga",
  301.             "America/Santiago",
  302.             "Pacific/Easter",
  303.             "Africa/Douala",
  304.             "Asia/Shanghai",
  305.             "Asia/Harbin",
  306.             "Asia/Chongqing",
  307.             "Asia/Urumqi",
  308.             "Asia/Kashgar",
  309.             "America/Bogota",
  310.             "America/Costa_Rica",
  311.             "America/Havana",
  312.             "Atlantic/Cape_Verde",
  313.             "America/Curacao",
  314.             "Indian/Christmas",
  315.             "Asia/Nicosia",
  316.             "Europe/Prague",
  317.             "Europe/Berlin",
  318.             "Africa/Djibouti",
  319.             "Europe/Copenhagen",
  320.             "America/Dominica",
  321.             "America/Santo_Domingo",
  322.             "Africa/Algiers",
  323.             "America/Guayaquil",
  324.             "Pacific/Galapagos",
  325.             "Europe/Tallinn",
  326.             "Africa/Cairo",
  327.             "Africa/El_Aaiun",
  328.             "Africa/Asmara",
  329.             "Europe/Madrid",
  330.             "Africa/Ceuta",
  331.             "Atlantic/Canary",
  332.             "Africa/Addis_Ababa",
  333.             "Europe/Helsinki",
  334.             "Pacific/Fiji",
  335.             "Atlantic/Stanley",
  336.             "Pacific/Chuuk",
  337.             "Pacific/Pohnpei",
  338.             "Pacific/Kosrae",
  339.             "Atlantic/Faroe",
  340.             "Europe/Paris",
  341.             "Africa/Libreville",
  342.             "Europe/London",
  343.             "America/Grenada",
  344.             "Asia/Tbilisi",
  345.             "America/Cayenne",
  346.             "Europe/Guernsey",
  347.             "Africa/Accra",
  348.             "Europe/Gibraltar",
  349.             "America/Godthab",
  350.             "America/Danmarkshavn",
  351.             "America/Scoresbysund",
  352.             "America/Thule",
  353.             "Africa/Banjul",
  354.             "Africa/Conakry",
  355.             "America/Guadeloupe",
  356.             "Africa/Malabo",
  357.             "Europe/Athens",
  358.             "Atlantic/South_Georgia",
  359.             "America/Guatemala",
  360.             "Pacific/Guam",
  361.             "Africa/Bissau",
  362.             "America/Guyana",
  363.             "Asia/Hong_Kong",
  364.             "America/Tegucigalpa",
  365.             "Europe/Zagreb",
  366.             "America/Port-au-Prince",
  367.             "Europe/Budapest",
  368.             "Asia/Jakarta",
  369.             "Asia/Pontianak",
  370.             "Asia/Makassar",
  371.             "Asia/Jayapura",
  372.             "Europe/Dublin",
  373.             "Asia/Jerusalem",
  374.             "Europe/Isle_of_Man",
  375.             "Asia/Kolkata",
  376.             "Indian/Chagos",
  377.             "Asia/Baghdad",
  378.             "Asia/Tehran",
  379.             "Atlantic/Reykjavik",
  380.             "Europe/Rome",
  381.             "Europe/Jersey",
  382.             "America/Jamaica",
  383.             "Asia/Amman",
  384.             "Asia/Tokyo",
  385.             "Africa/Nairobi",
  386.             "Asia/Bishkek",
  387.             "Asia/Phnom_Penh",
  388.             "Pacific/Tarawa",
  389.             "Pacific/Enderbury",
  390.             "Pacific/Kiritimati",
  391.             "Indian/Comoro",
  392.             "America/St_Kitts",
  393.             "Asia/Pyongyang",
  394.             "Asia/Seoul",
  395.             "Asia/Kuwait",
  396.             "America/Cayman",
  397.             "Asia/Aqtobe",
  398.             "Asia/Aqtau",
  399.             "Asia/Oral",
  400.             "Asia/Almaty",
  401.             "Asia/Qyzylorda",
  402.             "Asia/Vientiane",
  403.             "Asia/Beirut",
  404.             "America/St_Lucia",
  405.             "Europe/Vaduz",
  406.             "Asia/Colombo",
  407.             "Africa/Monrovia",
  408.             "Africa/Maseru",
  409.             "Europe/Vilnius",
  410.             "Europe/Luxembourg",
  411.             "Europe/Riga",
  412.             "Africa/Tripoli",
  413.             "Africa/Casablanca",
  414.             "Europe/Monaco",
  415.             "Europe/Chisinau",
  416.             "Europe/Podgorica",
  417.             "America/Marigot",
  418.             "Indian/Antananarivo",
  419.             "Pacific/Majuro",
  420.             "Pacific/Kwajalein",
  421.             "Europe/Skopje",
  422.             "Africa/Bamako",
  423.             "Asia/Rangoon",
  424.             "Asia/Ulaanbaatar",
  425.             "Asia/Hovd",
  426.             "Asia/Choibalsan",
  427.             "Asia/Macau",
  428.             "Pacific/Saipan",
  429.             "America/Martinique",
  430.             "Africa/Nouakchott",
  431.             "America/Montserrat",
  432.             "Europe/Malta",
  433.             "Indian/Mauritius",
  434.             "Indian/Maldives",
  435.             "Africa/Blantyre",
  436.             "America/Mexico_City",
  437.             "America/Cancun",
  438.             "America/Merida",
  439.             "America/Monterrey",
  440.             "America/Matamoros",
  441.             "America/Mazatlan",
  442.             "America/Chihuahua",
  443.             "America/Ojinaga",
  444.             "America/Hermosillo",
  445.             "America/Tijuana",
  446.             "America/Santa_Isabel",
  447.             "America/Bahia_Banderas",
  448.             "Asia/Kuala_Lumpur",
  449.             "Asia/Kuching",
  450.             "Africa/Maputo",
  451.             "Africa/Windhoek",
  452.             "Pacific/Noumea",
  453.             "Africa/Niamey",
  454.             "Pacific/Norfolk",
  455.             "Africa/Lagos",
  456.             "America/Managua",
  457.             "Europe/Amsterdam",
  458.             "Europe/Oslo",
  459.             "Asia/Kathmandu",
  460.             "Pacific/Nauru",
  461.             "Pacific/Niue",
  462.             "Pacific/Auckland",
  463.             "Pacific/Chatham",
  464.             "Asia/Muscat",
  465.             "America/Panama",
  466.             "America/Lima",
  467.             "Pacific/Tahiti",
  468.             "Pacific/Marquesas",
  469.             "Pacific/Gambier",
  470.             "Pacific/Port_Moresby",
  471.             "Asia/Manila",
  472.             "Asia/Karachi",
  473.             "Europe/Warsaw",
  474.             "America/Miquelon",
  475.             "Pacific/Pitcairn",
  476.             "America/Puerto_Rico",
  477.             "Asia/Gaza",
  478.             "Asia/Hebron",
  479.             "Europe/Lisbon",
  480.             "Atlantic/Madeira",
  481.             "Atlantic/Azores",
  482.             "Pacific/Palau",
  483.             "America/Asuncion",
  484.             "Asia/Qatar",
  485.             "Indian/Reunion",
  486.             "Europe/Bucharest",
  487.             "Europe/Belgrade",
  488.             "Asia/Novosibirsk",
  489.             "Asia/Novokuznetsk",
  490.             "Asia/Krasnoyarsk",
  491.             "Asia/Irkutsk",
  492.             "Asia/Yakutsk",
  493.             "Asia/Vladivostok",
  494.             "Asia/Sakhalin",
  495.             "Asia/Magadan",
  496.             "Asia/Kamchatka",
  497.             "Asia/Anadyr",
  498.             "Europe/Kaliningrad",
  499.             "Europe/Moscow",
  500.             "Europe/Volgograd",
  501.             "Europe/Samara",
  502.             "Asia/Yekaterinburg",
  503.             "Asia/Omsk",
  504.             "Africa/Kigali",
  505.             "Asia/Riyadh",
  506.             "Pacific/Guadalcanal",
  507.             "Indian/Mahe",
  508.             "Africa/Khartoum",
  509.             "Europe/Stockholm",
  510.             "Asia/Singapore",
  511.             "Atlantic/St_Helena",
  512.             "Europe/Ljubljana",
  513.             "Arctic/Longyearbyen",
  514.             "Europe/Bratislava",
  515.             "Africa/Freetown",
  516.             "Europe/San_Marino",
  517.             "Africa/Dakar",
  518.             "Africa/Mogadishu",
  519.             "America/Paramaribo",
  520.             "Africa/Juba",
  521.             "Africa/Sao_Tome",
  522.             "America/El_Salvador",
  523.             "America/Lower_Princes",
  524.             "Asia/Damascus",
  525.             "Africa/Mbabane",
  526.             "America/Grand_Turk",
  527.             "Africa/Ndjamena",
  528.             "Indian/Kerguelen",
  529.             "Africa/Lome",
  530.             "Asia/Bangkok",
  531.             "Asia/Dushanbe",
  532.             "Pacific/Fakaofo",
  533.             "Asia/Dili",
  534.             "Asia/Ashgabat",
  535.             "Africa/Tunis",
  536.             "Pacific/Tongatapu",
  537.             "Europe/Istanbul",
  538.             "America/Port_of_Spain",
  539.             "Pacific/Funafuti",
  540.             "Asia/Taipei",
  541.             "Africa/Dar_es_Salaam",
  542.             "Europe/Kiev",
  543.             "Europe/Uzhgorod",
  544.             "Europe/Zaporozhye",
  545.             "Europe/Simferopol",
  546.             "Africa/Kampala",
  547.             "Pacific/Johnston",
  548.             "Pacific/Midway",
  549.             "Pacific/Wake",
  550.             "America/Indiana/Petersburg",
  551.             "America/Indiana/Vevay",
  552.             "America/Chicago",
  553.             "America/Indiana/Tell_City",
  554.             "America/Indiana/Knox",
  555.             "America/Menominee",
  556.             "America/North_Dakota/Center",
  557.             "America/North_Dakota/New_Salem",
  558.             "America/North_Dakota/Beulah",
  559.             "America/Denver",
  560.             "America/Boise",
  561.             "America/Shiprock",
  562.             "America/Phoenix",
  563.             "America/Los_Angeles",
  564.             "America/Anchorage",
  565.             "America/Juneau",
  566.             "America/Sitka",
  567.             "America/Yakutat",
  568.             "America/Nome",
  569.             "America/Adak",
  570.             "America/Metlakatla",
  571.             "Pacific/Honolulu",
  572.             "America/New_York",
  573.             "America/Detroit",
  574.             "America/Kentucky/Louisville",
  575.             "America/Kentucky/Monticello",
  576.             "America/Indiana/Indianapolis",
  577.             "America/Indiana/Vincennes",
  578.             "America/Indiana/Winamac",
  579.             "America/Indiana/Marengo",
  580.             "America/Montevideo",
  581.             "Asia/Samarkand",
  582.             "Asia/Tashkent",
  583.             "Europe/Vatican",
  584.             "America/St_Vincent",
  585.             "America/Caracas",
  586.             "America/Tortola",
  587.             "America/St_Thomas",
  588.             "Asia/Ho_Chi_Minh",
  589.             "Pacific/Efate",
  590.             "Pacific/Wallis",
  591.             "Pacific/Apia",
  592.             "Asia/Aden",
  593.             "Indian/Mayotte",
  594.             "Africa/Johannesburg",
  595.             "Africa/Lusaka",
  596.             "Africa/Harare"
  597.         };
  598.         #endregion
  599.     }
  600.    
  601.     [DataContract]
  602.     public class TimeModel : IComparable<TimeModel>
  603.     {
  604.         public TimeModel()
  605.         {
  606.         }
  607.         [DataMember]
  608.         public string CountryCode { get; set; }
  609.         [DataMember]
  610.         public string ZoneName { get; set; }
  611.         [DataMember]
  612.         public string Abbreviation { get; set; }
  613.         [DataMember]
  614.         public int GMTOffset { get; set; }
  615.         [DataMember]
  616.         public bool DaylightSaving { get; set; }
  617.         [DataMember]
  618.         public double TimeStamp { get; set; }
  619.        
  620.         public bool IsError { get; set; }
  621.  
  622.         public override bool Equals(object obj)
  623.         {
  624.             if (obj == null)
  625.                 return false;
  626.             TimeModel other = obj as TimeModel;
  627.             if (other == null)
  628.                 return false;
  629.  
  630.             return  this.CountryCode        == other.CountryCode        &&
  631.                     this.ZoneName           == other.ZoneName           &&
  632.                     this.Abbreviation       == other.Abbreviation       &&
  633.                     this.GMTOffset          == other.GMTOffset          &&
  634.                     this.DaylightSaving     == other.DaylightSaving     &&
  635.                     this.TimeStamp          == other.TimeStamp;
  636.         }
  637.  
  638.         public override int GetHashCode()
  639.         {
  640.             unchecked
  641.             {
  642.                 int hash = 17;
  643.                 int salt = 29;
  644.  
  645.                 hash = hash * salt + this.CountryCode.GetHashCode();
  646.                 hash = hash * salt + this.ZoneName.GetHashCode();
  647.                 hash = hash * salt + this.Abbreviation.GetHashCode();
  648.                 hash = hash * salt + this.GMTOffset.GetHashCode();
  649.                 hash = hash * salt + this.DaylightSaving.GetHashCode();
  650.                 hash = hash * salt + this.TimeStamp.GetHashCode();
  651.  
  652.                 return hash;
  653.             }
  654.         }
  655.  
  656.         int IComparable<TimeModel>.CompareTo(TimeModel other)
  657.         {
  658.             return this.ZoneName.CompareTo(other.ZoneName);
  659.         }
  660.     }
  661. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement