如何在繁忙的 ASP.NET MVC 中定义全局变量
How to define a global variable in a busy ASP.NET MVC
在我的站点中,我调用了第三方 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
属性。但是我读过很多书说拥有全局变量不是一个好主意。考虑到我的网站每秒有很多请求,我的代码可以安全使用吗?谢谢。
您的代码不是线程安全的。
试试这个:
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 对象
或许,您可以使用 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;
}
}
}
}
您的代码不是 100% 安全的,因为它可能会在开始时创建多个 TimeLimiter 实例,并且根据周围的代码,这可能是一个问题。我猜这不会是一个大问题,但最好先正确编写代码。
这是 IoC 容器可以很好地处理的事情,但如果您不想使用它,可以使用 Lazy:
private static TimeLimiter rateLimiter = new Lazy(() =>
TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval));
public static TimeLimiter RateLimiter => rateLimiter.Value;
在我的站点中,我调用了第三方 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
属性。但是我读过很多书说拥有全局变量不是一个好主意。考虑到我的网站每秒有很多请求,我的代码可以安全使用吗?谢谢。
您的代码不是线程安全的。 试试这个:
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 对象
或许,您可以使用 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;
}
}
}
}
您的代码不是 100% 安全的,因为它可能会在开始时创建多个 TimeLimiter 实例,并且根据周围的代码,这可能是一个问题。我猜这不会是一个大问题,但最好先正确编写代码。
这是 IoC 容器可以很好地处理的事情,但如果您不想使用它,可以使用 Lazy:
private static TimeLimiter rateLimiter = new Lazy(() =>
TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval));
public static TimeLimiter RateLimiter => rateLimiter.Value;