如何在繁忙的ASP.NET MVC中定义全局变量

时间:2017-11-19 16:21:37

标签: c# asp.net asp.net-mvc throttling

在我的网站中,我称之为第三方API。为了避免达到其速率限制,我需要定义一个全局变量来排队请求。 I'm using RateLimiter任何更好的解决方案?)

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属性。但我已经读过很多关于拥有全局变量并不是一个好主意。考虑到我的网站每秒有很多请求,我的代码是否可以安全使用?感谢。

3 个答案:

答案 0 :(得分:1)

您的代码不是100%安全的,因为它可能在开始时创建多个TimeLimiter实例,并且根据周围的代码,它可能是个问题。我猜它不是一个大问题,但最好还是先写好代码。

这是IoC容器很好地处理的东西,但是如果你不想使用它,你可以使用Lazy:

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

答案 1 :(得分:0)

也许,您可以使用 lock 语句使其成为线程安全的。

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;
            }

        }
    }
}

答案 2 :(得分:-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; }
  }
}

或者使用您最喜欢的IoC容器创建SingleInstance对象