gdp*_*gdp 1 c# asynchronous throttling
我在我的应用程序中实现了一些请求限制.它基于使用MemoryCache和根据限制到期的项目.基本上我尝试检索一个缓存项目,如果它不在那里我继续发出请求,如果是他们我检查最后一个请求和锻炼下一个可用时间我可以提出请求.我的问题在于我必须等待提出请求.
//This is a shortened version of what im doing, but the includes the required code
public void ThrottleRequest(string webservice)
{
if (cache.TryGet(webservice))
{
var timeToWait = GetTimeToWaitFromSomewhere();
Wait(timeToWait);
}
}
public async void Wait(TimeSpan timeToWait)
{
await Task.Delay(timeToWait); //This doesnt work
Thread.Sleep(timeToWait); //This works
}
Run Code Online (Sandbox Code Playgroud)
问题在于等待方法.如果我使用thread.sleep数字匹配并且请求被正确限制(即每秒1个请求)但我永远不想在生产环境中使用它.那么在这里异步等待的正确方法是什么?我滥用API还是什么?
问题是你的Wait方法有一个返回类型void- 你基本上说,"开始等待,我会继续前进,忽略等待!"
你通常会把它当作:
public async Task ThrottleRequest(string webservice)
{
if (cache.TryGet(webservice))
{
var timeToWait = GetTimeToWaitFromSomewhere();
await Wait(timeToWait);
}
}
public async Task Wait(TimeSpan timeToWait)
{
await Task.Delay(timeToWait);
}
Run Code Online (Sandbox Code Playgroud)
虽然在那时,你的Wait方法毫无意义,你最好写:
public async Task ThrottleRequest(string webservice)
{
if (cache.TryGet(webservice))
{
var timeToWait = GetTimeToWaitFromSomewhere();
await Task.Delay(timeToWait);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我已将您的ThrottleRequest方法更改为异步并返回Task.目前尚不清楚你希望是什么呼吁Wait将实现自身的,但如果你试图引进异步,你需要了解你在做什么非常明确的-通常该方法调用异步方法将也被异步.
如果你真的只想暂停当前正在执行的线程ThrottleRequest,那么你根本不应该使用异步方法 - 你想要同步延迟,这正是这样Thread.Sleep做的.
我强烈怀疑你没有完全清楚你的代码目前在同步或异步方面的意图.我会从代码本身退一步,找出你实际期望它如何工作(例如,想想你想要的线程模型),然后再回到键盘上.
同时认为,已经发生的延迟之后,你就不会再检查缓存-这意味着,如果20个不同的线程每个进入你的方法一次,他们将所有最终击中Web服务,而不是只是其中之一做所以其余的使用缓存结果.