C# C语言中的节流方法#
我有一个方法可以向第三方API发出请求并从中返回响应。 由于这个API每1分钟只允许50个调用,我想限制我对这个API的请求 目前,我正在考虑使用Polly,并在代码中添加类似于wrapper的内容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
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可能出现的网络停机时间,但与节流无关
关于节流,我建议创建一些模式,在其中存储请求并以给定的速率处理它们
遗憾的是,这还有两个缺点:
注意:
.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次。。。