如何在托管ISP的服务器上实现Windows服务

时间:2012-10-17 13:06:49

标签: c# asp.net

我正在asp.net中完成一项任务,以便按特定时间间隔向用户发送通知电子邮件。

但问题是,由于服务器不是私有的,我无法在其上实现Windows服务。

有什么想法吗?

5 个答案:

答案 0 :(得分:5)

没有可靠的方法来实现这一目标。如果您无法在主机上安装Windows服务,则可以编写将发送电子邮件的端点(.aspx.ashx),然后在其他某个站点上购买将定期ping此端点的服务通过发送HTTP请求。显然,您应该将此端点配置为只能从您购买服务的提供商的IP地址访问,否则任何人都可以向端点发送HTTP请求并触发可能不合需要的过程。

进一步阅读:The Dangers of Implementing Recurring Background Tasks In ASP.NET

答案 1 :(得分:2)

有几种方法可以在不需要Windows服务的时间间隔内执行代码。

一个选项是使用Cache类 - 使用带有CacheItemRemovedCallback的{​​{3}}重载之一 - 这将在删除缓存项时调用。您可以一次又一次地使用此回调重新添加缓存项...

尽管如此,您需要做的第一件事就是联系托管公司,了解他们是否已经为您提供某种解决方案。

答案 2 :(得分:0)

您可以在服务器上设置计划任务,以使用所需操作调用程序。

答案 3 :(得分:0)

您始终可以使用System.Timer并按特定时间间隔创建呼叫。你需要注意的是,这必须运行一次,例如在应用程序启动时,但如果你有多个池,那么它可能运行更多次,你还需要访问一些数据库来读取你的数据动作。

using System.Timers;

var oTimer = new Timer();

    oTimer.Interval = 30000; // 30 second
    oTimer.Elapsed += new ElapsedEventHandler(MyThreadFun);
    oTimer.Start();    

private static void MyThreadFun(object sender, ElapsedEventArgs e)
{
    // inside here you read your query from the database
    // get the next email that must be send, 
    //  you send them, and mark them as send, log the errors and done.
}

为什么我选择系统计时器:  http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

更多单词

我在一个更复杂的类中使用它,它的工作正常。我还有什么要点。

  • 发信号通知应用程序停止,等待计时器结束。
  • 使用互斥和数据库同步工作。

答案 4 :(得分:0)

最简单的解决方案是利用global.asax应用程序事件

在应用程序启动事件中,将线程(或任务)创建为全局类中的静态单例变量。

线程/任务/工作项将有一个无限循环,而(true){...}与你的“类似服务”代码。

您还需要在循环中放置一个Thread.Sleep(60000),这样就不会占用不必要的CPU周期。

static void FakeService(object obj) {
    while(true) {
        try {
        // - get a list of users to send emails to
        // - check the current time and compare it to the interval to send a new email
        // - send emails
        // - update the last_email_sent time for the users
        } catch (Exception ex) {
            // - log any exceptions
            // - choose to keep the loop (fake service) running or end it (return)
        }
        Thread.Sleep(60000); //run the code in this loop every ~60 seconds
    }
}

编辑因为您的任务或多或少是一个简单的计时器作业,因此应用程序池重置或其他错误中的任何ACID类型问题都不适用,因为它可以重新启动并且保持卡车运输以及任何数据损坏。但是你也可以使用该线程简单地执行一个aspx或ashx的请求来保存你的逻辑。

new WebClient().DownloadString("http://localhost/EmailJob.aspx");