3

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

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

有任何想法吗?

4

5 回答 5

5

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

延伸阅读:The Dangers of Implementing Recurring Background Tasks In ASP.NET

于 2012-10-17T13:09:28.197 回答
2

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

一种选择是使用Cache类 - 使用一个Insert需要 a 的重载CacheItemRemovedCallback- 这将在缓存项被删除时调用。您可以使用此回调一次又一次地重新添加缓存项...

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

于 2012-10-17T13:11:58.643 回答
0

您可以在服务器上设置计划任务来调用具有所需操作的程序。

于 2012-10-17T13:10:35.430 回答
0

您始终可以使用 aSystem.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

更多的话

我在一个更复杂的类中使用它并且它的工作正常。我也提出了哪些观点。

  • 发出应用程序停止的信号,等待计时器结束。
  • 使用互斥锁和数据库来同步工作。
于 2012-10-17T13:21:32.080 回答
0

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

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

线程/任务/工作项将有一个无限循环 while(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");
于 2012-10-17T13:21:42.540 回答