매초마다 메서드를 호출하는 타이머가 있다고 가정합니다.많은 스레드가 세마포어를 기다리고 있습니다.
메서드는 비동기 (비동기이어야 함)이고 메서드는 SemaphoreSlim을 사용하여 동기화됩니다. 메서드를 완료하는 데 5 초가 걸립니다.
세마포어를 기다리는 스레드가 많이 있습니다. 사실입니까? 그게 문제 야? 이것은 타이머이기 때문에 점점 더 많은 쓰레드가 세마포어를 기다리게 될 것입니다.
이 문제를 어떻게 해결할 수 있습니까? 세마포어가 해제되지 않으면 기다릴 수 있습니까 (코드 건너 뛰기 만 가능)?
타이머 :
PoolReportTimer = new Timer(ReportTimerCallback, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
방법 :
이private static SemaphoreSlim semaphoreSlimValue = new SemaphoreSlim(1, 1);
private async void ReportTimerCallback(object state)
{
try
{
await semaphoreSlimValue.WaitAsync();
await Task.FromResult(0);
Thread.Sleep(5000);
}
finally
{
semaphoreSlim.Release();
}
}
편집 :
내가 비동기 방식의 모든 몇 초를보고 싶어. 그러나 메소드가 완료하는 데 많은 시간이 필요할 경우 이것이 문제가되지 않도록해야합니다.
편집 2 - 솔루션 :
private async void ReportTimerCallback(object state)
{
if (await semaphoreSlimValue.WaitAsync(10))
{
try
{
await Task.FromResult(0);
Thread.Sleep(5000);
}
finally
{
semaphoreSlim.Release();
}
}
}
설명하신 내용이 필요하지 않습니다. 이것은 XY 문제와 같은 냄새가납니다. 당신이하고 싶은 것을 묘사 할 수 있습니까? 코드와 다르지 않지만 달성하고자하는 것은 무엇입니까? – nvoigt
비동기 메서드에서 몇 초마다 보고서를 가져오고 싶습니다. 그러나 메소드가 완료하는 데 많은 시간이 필요할 경우 이것이 문제가되지 않도록해야합니다. – Raskolnikov
너무 오래 걸리면 어떨까요? 1 초 타이머에서 2 초가 걸립니다. 프로그램이 죽을 때까지 새로운 스레드를 스팸하고 싶습니까? 그리고 만약 당신이 * 기다리지 않고 하나를 끝내기를 원한다면 왜 대기와 세마포를해야합니까? – nvoigt