简述:
iis是一个很不错的服务器,有很多很好用的特性来支持网站运行,但有时候这些特性却会影响到我们开发者的一些操作。比如我们需要定时运行做一些操作,但由于iis的利用应用程序池来管理这种方式会让网站所在的进程在空闲(一段时间没人访问)时注销该线程,所以定时器是无法正常运行的。但利用asp.net的Cache机制是可以巧妙的实现能正常使用的定时器的。
运行效果:
该网站定时每一个小时给该网页添加一条记录,而且估计我这个站点几百年都不会有一个人来访问一次的,大部分时间都是处于空闲状态的。
怎么使用:
网站添加WebTimerLib类库的引用
在合适的位置编写以下一行代码
WebTimerLib.WebTimer timer = new WebTimerLib.WebTimer(new System.Threading.TimerCallback(TimeCallback), null, TimeSpan.FromSeconds(2), TimeSpan.FromHours(1));
这行代码表示2秒后没一个小时运行一次TimeCallback这个方法
具体每个参数会在源码里有注释
源码:
源码是在.net 3.5的环境下开发的,估计.net2.0也是可以编译通过的。
WebTimer类的代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 using System.Web.Caching; 7 using System.Web; 8 9 namespace WebTimerLib 10 { 11 /// <summary> 12 /// 可以正常在web使用的定时器 13 /// </summary> 14 public class WebTimer : IDisposable 15 { 16 /// <summary> 17 /// 初始化 Timer 类的新实例,使用 TimeSpan 值来度量时间间隔。 18 /// </summary> 19 /// <param name="callback">一个 TimerCallback 委托,表示要执行的方法。 </param> 20 /// <param name="state">一个包含回调方法要使用的信息的对象,或者为 空引用(在 Visual Basic 中为 Nothing)。 </param> 21 /// <param name="dueTime">TimeSpan,表示在 callback 参数调用它的方法之前延迟的时间量。指定 -1 毫秒以防止启动计时器。指定零 (0) 以立即启动计时器。 </param> 22 /// <param name="period">在调用 callback 所引用的方法之间的时间间隔。指定 -1 毫秒可以禁用定期终止。 </param> 23 /// <remarks> 24 /// 如果 dueTime 为零 (0),则立即调用 callback。如果 dueTime 是 -1 毫秒,则不会调用 callback;计时器将被禁用,但通过调用 Change 方法可以重新启用计时器。 25 /// 如果 period 为零 (0) 或 -1 毫秒,而且 dueTime 为正,则只会调用一次 callback;计时器的定期行为将被禁用,但通过使用 Change 方法可以重新启用该行为。 26 /// 为 callback 指定的方法应是可重入的,这是因为 ThreadPool 线程会调用该方法。该方法在以下两种情况下可以同时在两个线程池线程中执行:一是计时器间隔小于执行该方法所需的时间;二是所有线程池线程都在使用,并且多次对该方法进行排队。 27 /// </remarks> 28 public WebTimer(TimerCallback callback, Object state, TimeSpan dueTime, TimeSpan period) 29 { 30 _callback = callback; 31 _state = state; 32 _dueTime = dueTime; 33 _period = period; 34 Run(dueTime); 35 } 36 37 private TimerCallback _callback; 38 private object _state; 39 private TimeSpan _dueTime; 40 private TimeSpan _period; 41 private bool _isDisposing; 42 private DateTime _NewDoCallbackTime; 43 44 protected void Run(TimeSpan dueTime) 45 { 46 _NewDoCallbackTime = DateTime.Now.Add(dueTime); 47 HttpRuntime.Cache.Add(CacheID, this, null, _NewDoCallbackTime, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(CacheItemRemovedCallback)); 48 49 } 50 51 private void CacheItemRemovedCallback(String key, Object value, CacheItemRemovedReason reason) 52 { 53 WebTimer timer = (WebTimer)value; 54 if (reason == CacheItemRemovedReason.Expired) 55 { 56 timer._callback(_state); 57 timer.Run(this._period); 58 } 59 else if (!timer._isDisposing) 60 { 61 timer.Run(_NewDoCallbackTime - DateTime.Now); 62 } 63 } 64 65 /// <summary> 66 /// 更改计时器的启动时间和方法调用之间的时间间隔,使用 TimeSpan 值度量时间间隔。 67 /// </summary> 68 /// <param name="dueTime">一个 TimeSpan,表示在调用构造 Timer 时指定的回调方法之前的延迟时间量。指定负 -1 毫秒以防止计时器重新启动。指定零 (0) 以立即重新启动计时器。</param> 69 /// <param name="period">在构造 Timer 时指定的回调方法调用之间的时间间隔。指定 -1 毫秒可以禁用定期终止。 </param> 70 /// <returns></returns> 71 public bool Change(TimeSpan dueTime, TimeSpan period) 72 { 73 this._dueTime = dueTime; 74 this._period = period; 75 try 76 { 77 HttpRuntime.Cache.Remove(CacheID); 78 this.Run(this._dueTime); 79 return true; 80 } 81 catch (Exception) 82 { 83 return false; 84 } 85 } 86 87 private string _cacheID; 88 protected string CacheID 89 { 90 get 91 { 92 if (_cacheID == null) _cacheID = GetHashCode().ToString(); 93 return _cacheID; 94 } 95 } 96 97 #region IDisposable 成员 98 99 public void Dispose() 100 { 101 _isDisposing = true; 102 } 103 104 105 106 #endregion 107 108 } 109 }
补充:
对于我的书写能力我表示歉意,小时候语文没学好,文笔不好请见谅;能力水平有限,有什么说错的地方请多多指教;
关于转载,我不喜欢别人转载我的文章,觉得有价值的话就收藏到笔记之类软件,不会给搜索引擎收录的地方,我不太关注我的文章的版权问题,但我实在不喜欢自己在网上搜索资料的时候,搜到满满的一页是自己曾写过的一篇文章,实在恶心到我自己,我就注意到了一个情况,很多转载都不是为了学习的,而是一些公司不知道基于什么想法就转了过去,这样造成了搜索自己想要的资源会越来越难。但我发现如果是搜英文的资料的时候就很少有重复的,o(︶︿︶)o 唉,实在纠结啊!
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>