简体   繁体   English

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

[英]How to define a global variable in a busy ASP.NET MVC

In my site, I call a third party API. 在我的网站上,我调用了第三方API。 To avoid hitting its rate limit, I need to define a global variable to enqueue requests. 为了避免达到其速率限制,我需要定义一个全局变量来排队请求。 ( I'm using RateLimiter any better solution?) 我正在使用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;
            }
        }
    }
}

Then I'll use RateLimiter property. 然后,我将使用RateLimiter属性。 But I've read a lot that having a global variable is not a good idea. 但是我已经读了很多书,拥有一个全局变量并不是一个好主意。 Considering my site has a lot of requests per second, is my code safe to use? 考虑到我的网站每秒有很多请求,我的代码可以安全使用吗? Thanks. 谢谢。

Your code isn't 100% safe since it could create multiple instances of TimeLimiter in the beginning and depending on surrounding code, it could be a problem. 您的代码不是100%安全的,因为它可能在一开始就创建TimeLimiter的多个实例,并且取决于周围的代码,这可能是一个问题。 I'm guessing it wouldn't be a big problem, but it's better to write the code properly to begin with. 我猜这不是什么大问题,但是最好先编写正确的代码。

This is something an IoC container handles nicely, but if you don't want to use one, you could use Lazy: 这是IoC容器可以很好地处理的事情,但是如果您不想使用一个,可以使用Lazy:

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

Maybe, you can make it thread-safe by using lock statement. 也许可以通过使用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;
            }

        }
    }
}

Your code is not thread-safety. 您的代码不是线程安全的。 Try this: 尝试这个:

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

Or use your favorite IoC-container with creating SingleInstance object 或者使用您最喜欢的IoC容器创建SingleInstance对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM