简体   繁体   中英

C# Timer doesn't work correctly

I use Asp .NET Mvc 3 for creating web page and I need to change something in database after each 20 minutes... I set Timer in my Global.asax.cs file . Here is the code

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    Unit = new UnitOfWork();
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = 1200000; //20 minutes
    timer.Elapsed += new System.Timers.ElapsedEventHandler(Elapsed);
    timer.Start();
}

void Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Unit.Srvc.UpdateUserActivity();
}

Now I run it today, and what a pitty, it works only one time... After 20 minutes it change database and it's all.

PSYesteday I tested it in 20 seconds and it works fine. But,today it don't want to work correctly in 20 minutes interval. Thank you for help.

PS2 I used Stored Procedure for updating database.

PS3 Just now I detect that it works randomly :D In 5:32Am I run the program... It works in 5:52Am, doesn't work in 6:12Am, and works now(now is 6:49 Am, I don't know when it works).

Most likely cause is that your AppDomain is shutting down due to inactivity, which means the entire application is not running. The idle timeout is 20 minutes of inactivity, I think.

See this question:

How to keep ASP.NET assemblies in AppDomain alive?

To me it looks like your timer will be killed by garbage collection as you are not keeping a reference to it after it goes out of scope from Application_Start. Try adding:

Application["Whatever"] = timer;

You might be finding that your thread (from the IIS AppPool) is being recycled or shut down.

Web applications typically work best when used for request-response processing rather than this type of behaviour. It's not clear what you are up to, but assuming you are using SQL Server perhaps you could look at maintenance tasks or triggers if it involves denormalizing data (ie rolling up calculated data). If it involves data collected during the request-response process then perhaps you might look at using the web cache and some cache expiration operations for the delayed persistence.

My guess is too that the session simply expires but I would like to add a little extra.

Reading the code I guess (again) that you are marking the user in the database as 'not active' or disconnected or something like that. If so, do not use a timer to do this, instead, set the session expiration (when the user hasn't sent any requests for a certain period) to the required duration and put the code you want to run when that happens in the Session_OnEnd handler

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