2016-10-21 2 views
0

매초마다 메서드를 호출하는 타이머가 있다고 가정합니다.많은 스레드가 세마포어를 기다리고 있습니다.

메서드는 비동기 (비동기이어야 함)이고 메서드는 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(); 
       } 
      } 
     } 
+1

설명하신 내용이 필요하지 않습니다. 이것은 XY 문제와 같은 냄새가납니다. 당신이하고 싶은 것을 묘사 할 수 있습니까? 코드와 다르지 않지만 달성하고자하는 것은 무엇입니까? – nvoigt

+0

비동기 메서드에서 몇 초마다 보고서를 가져오고 싶습니다. 그러나 메소드가 완료하는 데 많은 시간이 필요할 경우 이것이 문제가되지 않도록해야합니다. – Raskolnikov

+0

너무 오래 걸리면 어떨까요? 1 초 타이머에서 2 초가 걸립니다. 프로그램이 죽을 때까지 새로운 스레드를 스팸하고 싶습니까? 그리고 만약 당신이 * 기다리지 않고 하나를 끝내기를 원한다면 왜 대기와 세마포를해야합니까? – nvoigt

답변

2

가 다른 스레드가 그것에 보류가있는 경우 세마포어를 기다리는 생략하려는 경우, 당신은하자 (A 시간 범위를 통과하려면 WaitAsync(TimeSpan) 방법을 사용할 수 있습니다 10 분의 1 초), 결과는 await입니다. 그것이 false 인 경우 누군가 다른 사람이 귀하의 리소스를 보유하고 있으며 귀하가 그 사실에 반응 할 수 있습니다.

+0

내 질문에 2 편집을 참조하십시오. 그게 네 생각이야? – Raskolnikov

+0

@Raskolnikov 아, 네. – nvoigt

+0

도움 주셔서 감사합니다. – Raskolnikov

관련 문제