0

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

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

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

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

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

4

2 回答 2

1

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

例如:

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 实例。

于 2013-04-04T22:40:52.353 回答
1

Application_Start 不是由新会话触发,而是由应用程序启动触发。如果您在 Application_Start 中初始化计时器,则无需担心多个计时器实例。

于 2013-04-08T22:29:47.057 回答