在httpmodule里写了一段代码,主要是通过timer定时执行任务。如果页面长时间没人访问了,web应用程序被回收了,这个定时执行的任务就挂掉了。有没有办法能将这个回收的时间延长,比如说调成24小时?以保证web定时任务的执行。

解决方案 »

  1.   

    把iis的回收机制关掉,或者设置间隔时间
      

  2.   

    我刚也找到了,在应用程序池属性里可以设置。还有其他方法设置吗?能够不用去修改iis配置的。
      

  3.   

    对于定时执行任务之类的,最好不要放在web程序里,那是很糟糕的事情,因为这样会占用资源,iis为什么会要去回收?就是了尽可能减少没用的资源。提供更多的资源给外部访问线程。
    你可以做一个windowservice程序放在web服务器上运行不就可以了?
      

  4.   

    我也正在寻找同样问题的答案,我现在就是使用windowservice来做的。但是有个问题,如果我要定期更新一些静态变量呢?windowservice好像就不大好实现了,毕竟不是不同的内存空间,那该怎么办呢?
      

  5.   


    可以用.net remoting来更新Windows Service里的变量达到通知目的。
      

  6.   


    哦?!remoting没试用,关注一下!
      

  7.   

    对于定时执行任务之类的,最好不要放在web程序里,那是很糟糕的事情,因为这样会占用资源,iis为什么会要去回收?就是了尽可能减少没用的资源。提供更多的资源给外部访问线程。
      

  8.   


    你的网站暴露出webservice给windowservice啊,这样windowservice每次更新调用webservice去更新数据不就可以了?
      

  9.   

    你这样设计绝对使不合理的,在httpModule里设置定时器,那么每一个web请求,都要通过Module,难道都要挂起24小时,这样没几个请求你的服务器就挂了。。这样太浪费资源了。。 你可以采用其它方式实现啊,比如Winservice定时调用你网站的webservice来实现
      

  10.   


    如果不考虑性能,你可以这么做,要知道,既然是静态变量的数据,那么读取应该是相当频繁的,io的读取是影响程序性能一个非常大的因素。与其把损耗放在读上,还不如做webservice来写,把损耗放在写上。因为这种写的操作室定时的,并且只会有一次。
      

  11.   

    用windowservice的好处还在于如果你有多台web服务器的话,你可以用一个service就解决了以前放在每台服务器的iis上做timer的问题,service只要定时调用这些服务器的webservice进行更新即可,至于服务器列表,你可以配在service的配置文件里就可以了。当然这有就会有单点故障的问题,就是如果windowservice crash掉了,所有更新就没有了。所以service的程序一定要保证不会自己crash。然后把这个service放到数据库服务器上,那么就非常稳定了,因为如果是服务器crash掉的话,要知道数据库也就没有了,那就不要谈这个service是否活着了,当然这个方案的前提是你的数据库服务器不是做分布式的,用cluster实现双机备份都可以用这个方案。
      

  12.   


    我的定时器只会有一个,不会重复执行的。重复的问题测试过。单独对一个web应用程序来说,如果访问量足够多的情况下,在默认设置的20分钟内,这个也不会被回收,情况和设置24小时(举例而已)才回收的情况大约差不多吧?当然如果一台机有多个web应用程序,那的确消耗会大……我当时不考虑用windowservice或sql定时任务来做的原因,其实是考虑我可能没办法直接去管理服务器。另外用winservice定时调用webservice的话,也是因为没办法直接管理服务器的情况,假如winservice不能安装到服务器上去,那就必须另外开一台机24小时跑了……
      

  13.   

    很奇怪,你的timer为什么要放在httpmodule里?你就放在某个程序模块了就可以了啊
    把你的timer声明称 readonly static timer = new Timer();
    看看是否会被垃圾回收器回收掉?
    我记得这样是不会被回收的,因为我写的cachemanager就是这么做的,cache后台会有个timer去不停的看cacheitem是否失效,失效了就清除掉。
      

  14.   

    每段时间timer里的数据自动持久化
    每次timer加载时再从持久化数据中取回要用的数据
      

  15.   

    建议放到global的application_start事件中,这样只要iis不挂,他会一直执行
      

  16.   

    突然有一点点不成熟的小想法,是不是可以用某些刷网站流量之类的方法来设置对这个web程序的访问呢,哈哈,仅仅是一点小想法,别见笑啊
      

  17.   


    我的是因为网站没人访问的时候,运行程序池回收了导致的问题在正常访问的情况下,也是静态的timer,运行没有问题。我的定时任务主要是对数据库数据做处理的,所以用winservice或者sql的定时任务都是可以完成的。正常情况下我也应该多考虑用后面两种方式去处理,只是现在的情况是有可能不能直接管理服务器导致的……
      

  18.   


    你把它定义为readonly看是否还会被回收,按理应该不会了,如果这个被回收了,就只能重新启动程序了,iis回收普通的静态变量是因为写程序的人可以对变量的数据判断并可重新加载的。对于readonly如果也会回收的话,那就是微软搞的东西自己打自己了。
    我对我的那个cachemanger做过在网站中的测试的,我还特意去iis主动回收了应用程序池,timer都还是在工作,按理应该不会被回收掉。
    但建议自己最好还是测试下。
      

  19.   


    还是会被回收啊!我是写在Global.asax中,代码如下:    public readonly static System.Threading.Timer t1 = new System.Threading.Timer(new TimerCallback(WriteLog), null, 0, 2000);
        
        void Application_Start(object sender, EventArgs e) 
        {
            //在应用程序启动时运行的代码
        }    private static void WriteLog(object arts)
        {
            //一个写日文本的类,用于每2秒把当前时间追加d:\log\log.txt文本中
            WriteToLog.WriteFile("D:\\Log\\", "Log.txt", DateTime.Now.ToString(), 0);
        }
    访问网站后,每2秒种都在写文件,可是在IIS中手动回收垃圾后,程序还是停止了,请问tmxk2002兄,是写错了还是怎么回事啊?
      

  20.   

    lz的专研精神让人佩服,但很明显的是方向上出了点问题asp.net和基于iis和http协议的,那么其受iis应用程序池的控制,受http这个无连接协议的控制如果单纯考虑http协议,http是无连接滴,又不能时时刻刻保证有人访问,那么可能的解决方法是 新开一个线程,然后在这个新线程的里去做你要做的事情,就能很好解决你最早的那个time out问题但是asp.net同时受iis管控,asp.net的执行实际是在iis程序池里管控滴,相当于是应用程序池进程下的某个线程
    而应用程序池是定时重启滴,不知道你观察过iis和进程的关系没有,如果有人访问某个站,iis会启动w3wp.exe去开启一个新的进程,同时去启动某个线程,并在线程里运行该站的实际代码。如果你仔细观察一下回收应用程序池时的进程状态,你回发现,在那一瞬间实际iis是重启开启了一个新的w3wp.exe进程,然后关闭原来w3wp.exe进程。现在就能很好解释你后面那个readonly的问题了,进程都已经变了,你认为那个readonly 还能起效吗?
    所以:你实际要选择的事情是 
    1.要能脱离http无状态的限制,保证你时时刻刻运行
    2.要能脱离iis管控,一直保持自己的进程呵呵,再看这两个要求不是window serviecs是啥??
      

  21.   

    分析的有一定道理
    你的代码好像没启动timer吧建议你把timer和需要更新的静态变量放到同一个静态类里
    然后在静态构造函数里去初始化timer的参数,以及start
    这样,即使像这位仁兄说的重新开了一个进程,那么只要访问静态变量,都会启动timer的。
      

  22.   

    可以自己访问自己的网页啊webclient定时访问一下 就像递归一样
      

  23.   

    可以在global中编码,当applicaton_end的时候把任务实例状态序列化到硬盘上
    在application_start事件触发的时候,再把硬盘的实例反序列化到你的httpmodule中,即可实现无缝timer运作.
    如果要考虑断电或者死机的情况,建议再做个定时器每隔5秒钟把你的任务实例序列化到硬盘上,这样至少可以保证最迟5秒内的数据完整性.