2017-11-19 12 views
0

내 사이트에서 제 3 자 API를 호출합니다. 속도 제한을 피하기 위해 요청을 대기열에 넣기 위해 전역 변수를 정의해야합니다. (I'm using RateLimiter 더 좋은 해결책?)바쁜 ASP.NET MVC에서 전역 변수를 정의하는 방법

namespace MySite.App_Start 
{ 
    public static class Global 
    { 
     public static int MaxCount { get; set; } = 30; 
     public static TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(1); 

     private static TimeLimiter rateLimiter; 
     public static TimeLimiter RateLimiter 
     { 
      get 
      { 
       if (rateLimiter == null) 
        rateLimiter = TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval); 

       return rateLimiter; 
      } 
     } 
    } 
} 

그럼 RateLimiter 속성을 사용합니다. 그러나 나는 전역 변수를 갖는 것이 좋은 생각이 아니라는 것을 많이 읽었습니다. 내 사이트가 초당 요청이 많다는 것을 고려하면 내 코드를 안전하게 사용할 수 있습니까? 감사.

+0

글쎄, C#을'에서'전역 변수 같은 것은 없다 , 그래서 ... –

+0

@CamiloTerevinto가 아닙니까? ummm 내 속성 인 'RateLimiter'에는 모든 요청에서 공유되는 전역 값이 있습니다. – Blendester

+0

정적 값이고 "글로벌"값이 아닙니다 –

답변

1

코드는 100 % 안전합니다. 나는 큰 문제는 아니 겠지만, 코드를 제대로 작성하는 것이 더 낫다. 게으른

는 IoC 컨테이너는 잘 처리하는 일이지만, 당신이 하나를 사용하지 않으려면, 당신은 사용할 수 있습니다

private static TimeLimiter rateLimiter = new Lazy(() => 
    TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval)); 
public static TimeLimiter RateLimiter => rateLimiter.Value; 
+0

IoC에 대해 조사했지만 복잡한 열린 탭이 많았습니다. IoC 컨테이너 하나를 제안 하시겠습니까? – Blendester

+0

하지만 나는'게으른'과 TimeLimiter로 갈 것이라고 생각합니다. – Blendester

+0

특정 것들에 깊이 빠져 들지 않으면 대부분 다르지 않습니다. 하지만 나는 그것이 정상적인 선택과 좋은 기능을 가지고 있으며 .NET 코어 등의 새로운 것들을 처리하기 위해 지속적으로 유지되고 있다고 생각하기 때문에 Autofac을 제안 할 것입니다. 또한 ASP.NET MVC (코어와 프리 코어 모두를위한 좋은 누겟 패키지가 있습니다.) – Allrameest

-1

코드가 스레드 안전하지 않습니다. 이 시도 :

public class Singleton 
{  
    protected Singleton() { } 
    private sealed class SingletonCreator 
    { 
    private static readonly Singleton instance = new Singleton(); 
    public static Singleton Instance { get { return instance; } } 
    } 
    public static Singleton Instance 
    { 
    get { return SingletonCreator.Instance; } 
    } 
} 

또는

+0

내 구현과 다른 점이 있습니까? (나는 사람들이 설명없이 할 때 투표를하지 않고 싫어했다.) – Blendester

+0

2 @Blendester : 차이가있다. 멀티 스레드 코드에서 'if (rateLimiter == null)'구조를 사용하면 nullReference 예외를 얻을 수 있습니다. 한 스레드가 RateLimiter 속성을 시작하지만 종료하지는 않기 때문입니다. 다른 속성은 완벽하게 inited 값을 얻을 수 있습니다. –

+0

고마워요 @anton – Blendester

0

어쩌면 SingleInstance 객체를 생성하여 좋아하는 IOC의 컨테이너를 사용하여, 당신은 잠금 문을 사용하여 스레드로부터 안전 할 수 있습니다. 그것은 처음에 TimeLimiter의 여러 인스턴스를 만들 수 있습니다 및 코드 주변에 따라서는 문제가 될 수 있기 때문에

public static class Global 
{ 
    public static int MaxCount { get; set; } = 30; 
    public static TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(1); 

    private static object _lockObject = new object(); 
    private static TimeLimiter rateLimiter; 
    public static TimeLimiter RateLimiter 
    { 
     get 
     { 
      lock (_lockObject) 
      { 
       if (rateLimiter == null) 
        rateLimiter = TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval); 
       return rateLimiter; 
      } 

     } 
    } 
} 
+0

여기서 성능이 중요했기 때문에 잠금을 사용하는 경우 [중복 잠금] (https://en.wikipedia.org/wiki/Double-checked_locking)을 사용하여 경합을 피하는 것이 좋습니다. – Allrameest