我们有一个在 ASP.NET 上运行的网站。我想运行一个服务,每 XX 小时检查一次数据库表,如果不满足某些条件,则执行一个操作(发送邮件)。
我们不能使用
- 作为托管服务器的 Windows 服务不是专用服务器。(我们只有控制面板)
- 用于发送邮件的 SQL 服务,因为我们使用 Access 2003 (mdb) 作为我们的数据库。它位于 App_Data
- IIS 也不可用
我们需要在服务器中进行某种轮询,这一点非常关键。
我们现在有点卡住了。我们有哪些选择?
我们有一个在 ASP.NET 上运行的网站。我想运行一个服务,每 XX 小时检查一次数据库表,如果不满足某些条件,则执行一个操作(发送邮件)。
我们不能使用
我们需要在服务器中进行某种轮询,这一点非常关键。
我们现在有点卡住了。我们有哪些选择?
您可以使用一个技巧来仅使用您的 ASP.NET Web 服务来模拟 Windows 服务。
它的要点如下:
在缓存中放置一个项目,其有效期等于您希望轮询数据库的频率。
添加从缓存中删除项目时触发的回调。在回调方法中,添加你的轮询代码来做你想做的事情(调用访问数据库、发送邮件等)
所以:在你的全局 asax 中,是这样的:
private const string DummyCacheItemKey = "pollingCacheKey";
protected void Application_Start(Object sender, EventArgs e)
{
RegisterCacheEntry();
}
private bool RegisterCacheEntry()
{
if( null != HttpContext.Current.Cache[ DummyCacheItemKey ] ) return false;
HttpContext.Current.Cache.Add( DummyCacheItemKey, "Test", null,
DateTime.MaxValue, TimeSpan.FromMinutes(1),
CacheItemPriority.Normal,
new CacheItemRemovedCallback( CacheItemRemovedCallback ) );
return true;
}
public void CacheItemRemovedCallback( string key,
object value, CacheItemRemovedReason reason)
{
Debug.WriteLine("Cache item callback: " + DateTime.Now.ToString() );
// Do the service works
DoWork();
ReregisterCacheItem();
}
虽然它并不理想,但它符合您的限制。
该技术的完整细节可以在这里找到:http: //www.codeproject.com/Articles/12117/Simulate-a-Windows-Service-using-ASP-NET-to-run-sc
它在这里提到
这是该链接的一些片段
private static CacheItemRemovedCallback OnCacheRemove = null;
protected void Application_Start(object sender, EventArgs e)
{
AddTask("DoStuff", 60);
}
private void AddTask(string name, int seconds)
{
OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
HttpRuntime.Cache.Insert(name, seconds, null,
DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable, OnCacheRemove);
}
public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
{
// do stuff here if it matches our taskname, like WebRequest
// re-add our task so it recurs
AddTask(k, Convert.ToInt32(v));
}
在我的测试中运行良好;徽章每 60 秒颁发一次,就像所有 > 用户的发条一样 - Jeff Atwood