TPL/Parallel.ForEach를 사용하면 단위 시간당 메소드 호출 횟수를 제한 할 수있는 기본 방법이 있습니다 (즉, 둘째). 이는 스레드 수를 제한하는 것과는 다릅니다. 아마도이 작업을 수행하기위한 간단한 해킹이있을 것입니다.병렬 호출에서 초당 실행을 제한하십시오.
답변
하나의 솔루션을 사용하여 다음 https://stackoverflow.com/a/7728872/356790
/// <summary>
/// This class limits the number of requests (method calls, events fired, etc.) that can occur in a given unit of time.
/// </summary>
class RequestLimiter
{
#region Constructors
/// <summary>
/// Initializes an instance of the RequestLimiter class.
/// </summary>
/// <param name="maxRequests">The maximum number of requests that can be made in a given unit of time.</param>
/// <param name="timeSpan">The unit of time that the maximum number of requests is limited to.</param>
/// <exception cref="ArgumentException">maxRequests <= 0</exception>
/// <exception cref="ArgumentException">timeSpan.TotalMilliseconds <= 0</exception>
public RequestLimiter(int maxRequests , TimeSpan timeSpan)
{
// check parameters
if (maxRequests <= 0)
{
throw new ArgumentException("maxRequests <= 0" , "maxRequests");
}
if (timeSpan.TotalMilliseconds <= 0)
{
throw new ArgumentException("timeSpan.TotalMilliseconds <= 0" , "timeSpan");
}
// initialize instance vars
_maxRequests = maxRequests;
_timeSpan = timeSpan;
_requestTimes = new Queue<DateTime>(maxRequests);
// sleep for 1/10th timeSpan
_sleepTimeInMs = Convert.ToInt32(Math.Ceiling(timeSpan.TotalMilliseconds/10));
}
#endregion
/// <summary>
/// Waits until an request can be made
/// </summary>
public void WaitUntilRequestCanBeMade()
{
while (!TryEnqueueRequest())
{
Thread.Sleep(_sleepTimeInMs);
}
}
#region Private Members
private readonly Queue<DateTime> _requestTimes;
private readonly object _requestTimesLock = new object();
private readonly int _maxRequests;
private readonly TimeSpan _timeSpan;
private readonly int _sleepTimeInMs;
/// <summary>
/// Remove requests that are older than _timeSpan
/// </summary>
private void SynchronizeQueue()
{
while ((_requestTimes.Count > 0) && (_requestTimes.Peek().Add(_timeSpan) < DateTime.Now))
{
_requestTimes.Dequeue();
}
}
/// <summary>
/// Attempts to enqueue a request.
/// </summary>
/// <returns>
/// Returns true if the request was successfully enqueued. False if not.
/// </returns>
private bool TryEnqueueRequest()
{
lock (_requestTimesLock)
{
SynchronizeQueue();
if (_requestTimes.Count < _maxRequests)
{
_requestTimes.Enqueue(DateTime.Now);
return true;
}
return false;
}
}
#endregion
}
다른 질문에 답한 것 같습니다. "실행을 제한하는"필요성 ("웹 API를 병렬로 호출")의 필요성 (http://stackoverflow.com/questions/16360733/in-parallel-call-limit-executions-per-second/16402417#comment23442116_16360733))는 제한보다 더 많은 실행/요청을하고 대기열에 대기열을 넣거나 대기열에 넣는 것을 지연시키는 것과 같은 초고속 복잡성 **을 의미하지 않습니다! –
나는 당신이 무엇을 말하려고하는지 전혀 모른다. 호출 횟수를 X/초로 제한하려고합니다. 이것은 API 호출을하기 전에 WaitUntilRequestCanBeMade()를 호출하여 수행됩니다. – SFun28
실행 횟수 (호출 등)를 제한하기 위해 대기열/큐에서 대기열에 넣을 필요가 없습니다. 필요한 제한보다 초당 더 많은 전화를 걸지 마십시오. 저것과 같이 쉬운! [내 대답은] (http://stackoverflow.com/a/16402417/200449) 나는 대기열/de-queuing없이 이러한 실현의 준비 코드 예제에 대한 참조를 주었다. 호출의 흐름이 통제 범위를 벗어난다면 귀하의 답변은 유효한 접근 방법이지만 게시 된 질문과는 아무런 관련이 없습니다. 당신은 질문을 게시하고 (다른 질문에 답을하고 그것을 받아들이십시오!) –
준비 표시 코드 샘플의 스레드 안전 버전을 만들기 위해 타이머입니다 :
- for .NET 4.0 TPL이 하나를 놓치지 마세요,이입니다 모든 시간과 모든 사람들의 굉장한 프로젝트!
async/wait
를 사용 - in C# 5.0/.NET 4.5 , WPF
코드 대하여 반응성 확장하여 샘플/예 (RX) :
이 솔루션은 각 스레드의 시작 사이에 지연을 적용하고 요구 사항을 채우십시오.
private SemaphoreSlim CooldownLock = new SemaphoreSlim(1, 1);
private DateTime lastAction;
private void WaitForCooldown(TimeSpan delay)
{
CooldownLock.Wait();
var waitTime = delay - (DateTime.Now - lastAction);
if (waitTime > TimeSpan.Zero)
{
Task.Delay(waitTime).Wait();
lastAction = DateTime.Now;
}
lastAction = DateTime.Now;
CooldownLock.Release();
}
public void Execute(Action[] actions, int concurrentThreadLimit, TimeSpan threadDelay)
{
if (actions.Any())
{
Parallel.ForEach(actions,
new ParallelOptions() { MaxDegreeOfParallelism = concurrentThreadLimit},
(currentAction) =>
{
WaitForCooldown(threadDelay);
currentAction();
});
}
}
- 1. 이 프로그램이 병렬 실행을 도입합니까?
- 2. make : 일부 대상의 병렬 실행을 비활성화합니다.
- 3. Atlassian Bamboo에서 병렬 실행을 실행할 수 없습니까?
- 4. Pypy의 스택없는 스레드 옵션이 병렬 실행을 지원합니까?
- 5. 녹에서 병렬 실행을 비활성화하는 방법은 무엇입니까?
- 6. 시간 초과 및 병렬 matlab 실행을 죽일
- 7. SSIS에서 병렬 OLE DB 명령 실행을 방지합니다.
- 8. http 동사 nginx 요청을 제한하십시오.
- 9. 초당 실행되는 함수, 작동하지만 0.5 초당 같음
- 10. 병렬 실행을 위해 스레드간에 트랜잭션을 전달하는 방법은 무엇입니까?
- 11. 병합 테이블을 사용할 때 MonetDB가 병렬 쿼리 실행을 지원합니까?
- 12. "동시성"제한 10 개가 병렬 슬라이스 실행을 보장합니까?
- 13. 안드로이드 - 여러 애플 리케이션에서 같은 서비스의 병렬 실행을 피하십시오.
- 14. SBT에서 scct : test에 대한 병렬 실행을 비활성화 하시겠습니까?
- 15. boost asio io_service는 두 개의 병렬 호출 체인의 실행을 보장합니까?
- 16. Java Stream의 단일 단계에서 병렬 실행을 사용하는 방법
- 17. SQLLDR/SQL 로더를 사용하여 병렬 실행을 실행하는 솔루션
- 18. WCF 호출에서 요청 인수에 따라 병렬 처리가 수행됩니까?
- 19. 초당 프레임
- 20. Gradle을 병렬
- 21. 초당 로우 레일 잡글 요청 받기 (초당 8-15 회)
- 22. 명령없이 SSH-bash를 제한하십시오.
- 23. 모델의 레코드 수를 제한하십시오.
- 24. 자바의 제네릭 클래스를 제한하십시오.
- 25. 숫자를 및로 제한하십시오. 입력란에
- 26. Last.fm API에서 user.getWeeklyAlbumChart를 제한하십시오.
- 27. 경로에 허용되는 메소드를 제한하십시오.
- 28. 데이터 테이블 필드를 제한하십시오.
- 29. htaccess 파일의 RewriteRule을 제한하십시오.
- 30. Google지도 V3을 1로 제한하십시오.
정확히 무엇이 필요하며 왜 필요한지 더 자세히 설명해 주시겠습니까? – svick
웹 API를 병렬로 호출해야하지만 API는 초당 호출 수를 제한합니다. 나는 그 한계에 머무르고 싶다. – SFun28