2

我们有一个在 ASP.NET 上运行的网站。我想运行一个服务,每 XX 小时检查一次数据库表,如果不满足某些条件,则执行一个操作(发送邮件)。

我们不能使用

  1. 作为托管服务器的 Windows 服务不是专用服务器。(我们只有控制面板)
  2. 用于发送邮件的 SQL 服务,因为我们使用 Access 2003 (mdb) 作为我们的数据库。它位于 App_Data
  3. IIS 也不可用

我们需要在服务器中进行某种轮询,这一点非常关键。
我们现在有点卡住了。我们有哪些选择?

4

2 回答 2

2

您可以使用一个技巧来仅使用您的 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

于 2012-06-06T10:59:52.823 回答
2

它在这里提到

ASP.NET 中的简单后台任务

这是该链接的一些片段

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

于 2012-06-07T06:55:28.487 回答