C#中的油门方法

我有向某些 3rd 方 API 发出请求并从中返回响应的方法。由于此 API 每 1 分钟仅允许 50 次调用,因此我想限制对此 API 的请求。


目前我正在考虑使用 Polly 并在我的代码中添加诸如包装器之类的东西


var policy = Policy.Handle<HttpRequestException>()

                   .WaitAndRetryForever(retryAttempt => TimeSpan.FromMinutes(1));


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

                           .ConfigureAwait(false));


return response;

但也许这里有更好的方法来做到这一点。


Helenr
浏览 221回答 2
2回答

holdtom

Polly很好,我们在我们的基础设施中使用它在我们的微服务之间进行重试机制,但是我不推荐.WaitAndRetryForever,因为它听起来真的很危险,就像@Stefan 说的那样。如果第 3 方 API 在 30 分钟内进行维护/停机/无响应会发生什么我知道它不会经常发生,但仍然发生。我会建议使用Polly来克服网络问题。例如,第 3 方 API 可能的网络停机时间,但与节流无关。关于节流,我建议创建一些基于队列的模式,您可以在其中存储请求并以给定的速率处理它们。可悲的是,这还有两个缺点:您将需要在您的一端实现一些逻辑,以便此队列不会变得非常大并使您的进程消耗大量内存。如果有人等待超过一定时间才能收到他们的回复,这可能是糟糕的用户体验。由于我不知道您的 API 的性质,因此就我所能提供的建议而言,您必须决定这是否适合您。祝你好运!注意:&nbsp;.waitAndRetryForever如果您将其用于内部通信并且想要放松服务级别协议,那还不错。(例如,您不希望您的整个基础架构仅仅因为一项服务死亡而崩溃)。

慕标琳琳

我更喜欢控制一切(根据需要自定义)您还可以扩展工作人员以并行发出多个请求例子Worker worker = new Worker();worker.OnRetry += (id) =>{&nbsp; //called when error occurs&nbsp; //here you can wait as you want and send next request};worker.OnRespnse += (sender, success) =>{&nbsp; //called on response&nbsp; //customize success depend on response status-code/body&nbsp; //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{&nbsp; &nbsp; class Worker&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public delegate void OnRetryDelegate(int id);&nbsp; &nbsp; &nbsp; &nbsp; public event OnRetryDelegate OnRetry;&nbsp; &nbsp; &nbsp; &nbsp; public delegate void OnRespnseDelegate(Worker sender, bool success);&nbsp; &nbsp; &nbsp; &nbsp; public event OnRespnseDelegate OnRespnse;&nbsp; &nbsp; &nbsp; &nbsp; public Worker()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Id = IdProvider.GetNewId();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thread = new Thread(new ThreadStart(ExecuteAsync));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thread.Start();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; private readonly Thread thread;&nbsp; &nbsp; &nbsp; &nbsp; public string Number;&nbsp; &nbsp; &nbsp; &nbsp; public bool Idle { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public bool ShutDown { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public bool Started { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public int Id { get; private set; }&nbsp; &nbsp; &nbsp; &nbsp; public PostData { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public void Start(string postData)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PostData = postData;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Idle = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Started = true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; private void ExecuteAsync()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (!ShutDown)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.Sleep(1500);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Idle)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Idle = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Number == "terminate")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShutDown = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var request = (HttpWebRequest) WebRequest.Create("https://example.com");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var data = Encoding.ASCII.GetBytes(postData);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Debug.Print("send:&nbsp; " + postData);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request.Method = "POST";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request.ContentType = "application/x-www-form-urlencoded";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request.ContentLength = data.Length;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using (var stream = request.GetRequestStream())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stream.Write(data, 0, data.Length);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var response = (HttpWebResponse) request.GetResponse();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Debug.Print(responseString);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (responseString.Contains("something"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnRespnse?.Invoke(this, true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch (Exception)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnRetry?.Invoke(Id);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnRespnse?.Invoke(this, false);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP