Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的节流方法#_C#_Api_Httprequest_Throttling - Fatal编程技术网

C# C语言中的节流方法#

C# C语言中的节流方法#,c#,api,httprequest,throttling,C#,Api,Httprequest,Throttling,我有一个方法可以向第三方API发出请求并从中返回响应。 由于这个API每1分钟只允许50个调用,我想限制我对这个API的请求 目前,我正在考虑使用Polly,并在代码中添加类似于wrapper的内容 var policy = Policy.Handle<HttpRequestException>() .WaitAndRetryForever(retryAttempt => TimeSpan.FromMinutes(1)); var res

我有一个方法可以向第三方API发出请求并从中返回响应。 由于这个API每1分钟只允许50个调用,我想限制我对这个API的请求

目前,我正在考虑使用Polly,并在代码中添加类似于wrapper的内容

var policy = Policy.Handle<HttpRequestException>()
                   .WaitAndRetryForever(retryAttempt => TimeSpan.FromMinutes(1));

var response = await policy.ExecuteAsync(async () => await DoApiCallAsync()
                           .ConfigureAwait(false));

return response;
var policy=policy.Handle()
.WaitAndRetryForever(retrytry=>TimeSpan.frommins(1));
var response=await policy.ExecuteAsync(异步()=>await-DoApiCallAsync())
.configurewait(false));
返回响应;

但也许这是更好的方法。

Polly
很好,我们在我们的基础设施中使用它来实现微服务之间的重试机制,但我不推荐
.WaitAndRetryForever
,因为它听起来确实像@Stefan所说的那样危险。如果第三方API在30分钟内出现维护/停机/无响应,会发生什么?我知道这种情况并不经常发生,但仍然存在

我建议使用
Polly
克服网络问题。例如,第三方API可能出现的网络停机时间,但与节流无关

关于节流,我建议创建一些模式,在其中存储请求并以给定的速率处理它们

遗憾的是,这还有两个缺点:

  • 您需要在您的端实现一些逻辑,以便该队列不会变得非常大,并使您的进程消耗大量内存
  • 如果有人为了收到他们的响应而等待的时间超过了一定的时间,这可能是糟糕的用户体验
  • 因为我不知道你的API的性质,这是我所能接受的建议,你必须决定这是否适合你。祝你好运


    注意:
    .waitAndRetryForever
    如果您使用它进行内部沟通,并且希望放松自己的控制,那么它就不是那么糟糕了。(例如,您不希望因为一项服务死亡而导致整个基础设施崩溃)。

    我更希望控制一切(根据需要定制)

    您还可以扩展工作线程以并行地发出多个请求

    范例

    Worker worker = new Worker();
    worker.OnRetry += (id) =>
    {
      //called when error occurs
      //here you can wait as you want and send next request
    };
    worker.OnRespnse += (sender, success) =>
    {
      //called on response
      //customize success depend on response status-code/body
      //here you can wait as you want and send next request
    };
    worker.Start("request body");
    //you can start this worker over and over
    
    工人阶级

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace app
    {
        class Worker
        {
    
            public delegate void OnRetryDelegate(int id);
    
            public event OnRetryDelegate OnRetry;
    
            public delegate void OnRespnseDelegate(Worker sender, bool success);
    
            public event OnRespnseDelegate OnRespnse;
    
            public Worker()
            {
                Id = IdProvider.GetNewId();
                thread = new Thread(new ThreadStart(ExecuteAsync));
                thread.Start();
            }
    
            private readonly Thread thread;
            public string Number;
            public bool Idle { get; set; }
            public bool ShutDown { get; set; }
            public bool Started { get; set; }
            public int Id { get; private set; }
            public PostData { get; set; }
    
            public void Start(string postData)
            {
                PostData = postData;
                Idle = true;
                Started = true;
            }
    
            private void ExecuteAsync()
            {
                while (!ShutDown)
                {
                    Thread.Sleep(1500);
                    if (Idle)
                    {
                        Idle = false;
                        if (Number == "terminate")
                        {
                            ShutDown = true;
                            return;
                        }
    
                        try
                        {
                            var request = (HttpWebRequest) WebRequest.Create("https://example.com");
                            var data = Encoding.ASCII.GetBytes(postData);
                            Debug.Print("send:  " + postData);
                            request.Method = "POST";
                            request.ContentType = "application/x-www-form-urlencoded";
                            request.ContentLength = data.Length;
                            using (var stream = request.GetRequestStream())
                            {
                                stream.Write(data, 0, data.Length);
                            }
                            var response = (HttpWebResponse) request.GetResponse();
                            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                            Debug.Print(responseString);
                            if (responseString.Contains("something"))
                                OnRespnse?.Invoke(this, true);
                        }
                        catch (Exception)
                        {
                            OnRetry?.Invoke(Id);
                        }
    
                        OnRespnse?.Invoke(this, false);
                    }
                }
            }
        }
    }
    

    您当前的代码有效吗?如果是这样,可能更合适。如果它不起作用,你需要明确说明什么是不起作用的。一般来说:
    WaitAndRetryForever
    听起来很危险。@Stefan,是的,也许在这里至少会有3次。。。