【问题标题】:Share an object instance between multiple session/application instances in ASP.NET MVC在 ASP.NET MVC 中的多个会话/应用程序实例之间共享一个对象实例
【发布时间】:2013-04-09 06:29:47
【问题描述】:

我正在为日志监视器开发一个项目,并且我正在使用带有SignalR 的 ASP.NET 应用程序。

该应用程序的主要目标是在不同位置(LCD 监视器)的多个客户端中提供错误日志监视器。每当在数据库中创建日志错误时,应用程序都应该通知所有客户端新的错误。

我想在 Web 应用程序中创建一个静态的 Timer 变量,它将由 Application_Start 方法启动。

但是,知道应用程序每个会话只有一个线程,我认为 Web 服务器将有很多计时器一起运行。

我需要知道如何使这个Timer 实例对于网络服务器中的所有会话实例都是唯一的

【问题讨论】:

  • 定时器是干什么用的?每个间隔它都会检查日志数据库是否有新错误?
  • @Psytronic 是的,它会检查数据库是否有新错误,如果有新错误,SignalR 连接将向所有客户端广播。
  • 那你为什么想要一个独特的计时器呢?一个计时器还不够,因为您可以使用 signalR 一次将消息推送到所有连接的客户端
  • 但是您只需要一个计时器,因为您只需要进行一次数据库检查,并且信号器可以推送到所有连接的客户端。另外,快速阅读一下; haacked.com/archive/2011/10/16/…
  • Application_Start 不是由新会话触发的,而是由应用程序启动触发的。你没有你认为你有的问题。

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


【解决方案1】:

Application_Start 不是由新会话触发,而是由start of the application 触发。如果你在 Application_Start 中初始化你的定时器,你就不用担心多个定时器实例了。

【讨论】:

    【解决方案2】:

    您可以创建一个具有计时器的实例类。

    例如:

    public class MyTimerHolder
        {
            private static Lazy<MyTimerHolder> _instance = new Lazy<MyTimerHolder>(() => new MyTimerHolder());
            private readonly TimeSpan _checkPeriod = TimeSpan.FromSeconds(3);
            private IHubContext _hubProxy;
            // Threaded timer
            private Timer _timer;
    
            public MyTimerHolder()
            {
                _timer = new Timer(CheckDB, null, _checkPeriod, _checkPeriod);
            }
    
            public void BroadcastToHub(IHubContext context)
            {
                _hubProxy = context;
            }
    
            public void CheckDB(object state)
            {
                if (_hubProxy != null)
                {
                    // Logic to check your database
    
                    _hubProxy.Clients.All.foo("Whatever data you want to pass");
                }
            }
    
            public static MyTimerHolder Instance
            {
                get
                {
                    return _instance.Value;
                }
            }
        }
    

    然后您可以在任何时候从任何方法更改 hubContext。因此,假设您想向连接到集线器“MyDBCheckHub”的客户端广播。在您的应用程序的任何时候,您所要做的就是:

    MyTimerHolder.Instance.BroadcastToHub(GlobalHost.ConnectionManager.GetHubContext<MyDBCheckHub>());
    

    你可以在你的应用程序开始或任何你喜欢的地方抛出这个,在应用程序域中只有 1 个 MyTimerHolder 实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多