Пример #1
0
        private async void Run(HttpClient client)
        {
            var hadFailed = false;

            for (; ;)
            {
                Item item;
                lock (_Items)
                {
                    for (; ;)
                    {
                        if (_Items.Count == 0)
                        {
                            return;
                        }
                        item = _Items[0];
                        if (item.Retry <= 0 || item.CompletionSource.Task.IsCompleted)
                        {
                            _Items.RemoveAt(0);
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                try
                {
                    var wait = _LastRequest.AddMilliseconds(_Interval) - DateTime.Now;
                    if (wait > TimeSpan.Zero)
                    {
                        await Task.Delay(wait);
                    }

                    var url = new SignedRequestHelper(AccessKeyId, SecretKey, "webservices." + item.Destination).Sign(new Dictionary <string, string>()
                    {
                        ["Service"]        = "AWSECommerceService",
                        ["Operation"]      = "ItemLookup",
                        ["AWSAccessKeyId"] = AccessKeyId,
                        ["AssociateTag"]   = AssociateTag,
                        ["ItemId"]         = item.Asin,
                        ["IdType"]         = "ASIN",
                        ["ResponseGroup"]  = "Images,ItemAttributes,EditorialReview",
                    });

                    var res = (await client.FollowRedirectAsync(url.ToUri()).ConfigureAwait(false)).Message;
                    _LastRequest = DateTime.Now;

                    if (res.StatusCode == HttpStatusCode.ServiceUnavailable)
                    {
                        if (hadFailed)
                        {
                            _Interval = Math.Min(1280, _Interval << 1);
                        }
                        else
                        {
                            hadFailed = true;
                        }
                        continue;
                    }
                    hadFailed = false;

                    res.EnsureSuccessStatusCode();

                    var s = await res.Content.ReadAsStringAsync().ConfigureAwait(false);

                    item.CompletionSource.TrySetResult(ParseResponse(s, item));
                }
                catch (Exception ex)
                {
                    lock (_Items)
                    {
                        if (--item.Retry > 0)
                        {
                            continue;
                        }
                        else
                        {
                            _Items.Remove(item);
                        }
                    }
                    item.CompletionSource.TrySetException(ex);
                }
            }
        }