View difference between Paste ID: 5bMWicD4 and vAyDA4G4
SHOW: | | - or go back to the newest paste.
1
using Newtonsoft.Json;
2-
using System.Collections.Concurrent;
2+
3-
using RestAPIStoreApp.Management.Database;
3+
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-
                      while (!hasMutex)
97+
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
}