简体   繁体   中英

Share an object instance between multiple session/application instances in ASP.NET MVC

I am developing a project for a log monitor and I am using an ASP.NET application with SignalR .

The main objective of the application is to provide a monitor of error logs in multiple clients across different locations (LCD monitors). Every moment when a log error is created in database, the application should notify all the clients with the new error.

I am wondering to create a static Timer variable in the web application, that will be started by the Application_Start method.

But, knowing the application will have a single thread per session, I think the web server will have a lot of timers running together.

I need to know how to make this Timer instance unique for all the session instances in the web server.

You can create an instance class that has a timer.

For instance:

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

Then you can change the hubContext at any point from any method. So lets say you want to broadcast to clients connected to hub "MyDBCheckHub". At any point in your application all you have to do is:

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

You could throw this in your application start or wherever you please, there'll only be 1 instance of MyTimerHolder within the app domain.

Application_Start is not triggered by a new session, but by the start of the application . If you initialize your timer in Application_Start, you don't need to worry about multiple timer instances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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