ASP .NET 中的重复任务

发布于 2024-12-23 07:43:47 字数 352 浏览 2 评论 0原文

我有一个 ASP .NET 网站在 GoDaddy 上的共享环境中运行。该应用程序是一种基于订阅的服务,具有向用户定期计费的选项。

每个小时,我们都需要将用户数据与我们的支付处理器同步,以更新已升级或取消帐户的用户。支付处理器没有调用 URL 或以其他方式通知我们更改的机制。

问题:我们需要创建一个后台线程,以预定义的时间间隔运行一些代码。有一些关于 .NET 中后台任务的好文章,但我确信,可能有一种更简单的方法来解决这个问题。也许是一个可以调用函数的应用程序范围的计时器等。

限制:共享环境不允许Windows服务,外部应用程序,完全信任等。

由于这是一个生产应用程序,我想使用尽可能安全的方法而不是令人费解的 IIS。

I have an ASP .NET website running on GoDaddy in a shared environment. The application is a subscription-based service with options for recurring billing to users.

Every hour, we need to synchronize user data with our payment processor to update users who have upgraded or cancelled their accounts. The payment processor, does not have a mechanism for calling a URL or otherwise notifying us of changes.

The problem: We need to create a background thread that runs some code at a predefined interval. There are some good articles about background tasks in .NET but I am sure, there could be a simpler way around this. Maybe an application-wide timer that can call a function, etc.

The limitation: Shared environment does not allow windows services, external applications, full-trust, etc.

Since this is a production application, I would like to use the safest approach possible rather than arm-twisting IIS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

木緿 2024-12-30 07:43:47

我遇到了类似的问题,我正在开发 ASP 概念验证,并使用后台线程来执行可能需要几个小时的任务。问题是,ASP.Net 可以随时回收 AppDomain(杀死我的后台线程)。

为了防止这种情况,您可以将后台线程注册到 ASP.Net,这样它就会通知您的线程关闭。为此,请实现以下接口:

public interface IRegisteredObject
{
    void Stop(bool immediate);
}

并使用以下静态方法将对象注册到 ASP:

HostingEnvironment.RegisterObject(this);

当 ASP.NET 拆除 AppDomain 时,它将首先尝试对所有已注册对象调用 Stop 方法。在大多数情况下,它会调用此方法两次,一次将立即设置为 false。这给了你的代码一些时间来完成它正在做的事情。 ASP.NET 为 IRegisteredObject 的所有实例提供总共 30 秒的时间来完成其工作,而不是每个实例 30 秒。在该时间跨度之后,如果还剩下任何已注册的对象,它将再次调用它们并将立即设置为 true。

通过阻止 Stop 方法返回(通过在工作线程繁忙时锁定字段),我们阻止 ASP 关闭 AppDomain,直到我们的工作完成。

public void Stop(bool immediate)
{
    lock (_lock)
    {
        _shuttingDown = true;
    }
    HostingEnvironment.UnregisterObject(this); 
}

public void DoWork(Action work)
{
    lock (_lock)
    {
        if (_shuttingDown)
        {
            return;
        }
        work();
    }
}

使用任务而不是操作来从取消选项中受益。对于您的具体情况,您可以启动一个计时器来执行这样的任务。

附言。这是一种 hack,ASP 并不意味着运行后台任务,因此请尽可能使用 Windows 服务或 WCF 服务!我使用它是因为它简化了开发、维护和安装。

有关详细信息,请参阅我的来源:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

I had a similar problem, I'm developing a ASP proof of concept and use a background thread that performs a task that could take several hours. Problem is, ASP.Net can recycle the AppDomain at anytime (killing my background thread).

To prevent this, you can register your background thread to ASP.Net so it will notify your thread to shut down. To do this implement the following interface:

public interface IRegisteredObject
{
    void Stop(bool immediate);
}

And register your object to ASP using the following static method:

HostingEnvironment.RegisterObject(this);

When ASP.NET tears down the AppDomain, it will first attempt to call Stop method on all registered objects. In most cases, it’ll call this method twice, once with immediate set to false. This gives your code a bit of time to finish what it is doing. ASP.NET gives all instances of IRegisteredObject a total of 30 seconds to complete their work, not 30 seconds each. After that time span, if there are any registered objects left, it will call them again with immediate set to true.

By preventing the Stop method from returning (by locking a field when the worker is busy), we stop ASP from shutting down the AppDomain until our work is finished.

public void Stop(bool immediate)
{
    lock (_lock)
    {
        _shuttingDown = true;
    }
    HostingEnvironment.UnregisterObject(this); 
}

public void DoWork(Action work)
{
    lock (_lock)
    {
        if (_shuttingDown)
        {
            return;
        }
        work();
    }
}

Use a Task instead of action to benefit from cancellation options. For your specific case you could start a timer that executes tasks like this.

PS. This is a hack and ASP isn't meant to run background tasks so use a windows service or WCF service when possible! I use this since it simplifies development, maintenance and installation.

For more information see my source: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

东风软 2024-12-30 07:43:47

要更新 2018 年 - Hangfire NuGet 包非常适合此目的

To update for 2018 - The Hangfire NuGet package is perfect for this

暖树树初阳… 2024-12-30 07:43:47

由于没有答案,我想我会发布我的解决方案,以防它对其他人有帮助。

无论如何,这都不是理想的方法,但对于那些可能从中受益的人来说,我在另一个 Linux 托管帐户上创建了一个 cron 作业,我们必须调用所需的 ASP .NET url。管理令人恐惧,但确实有效。

Since there were no answers, I thought I'd post my solution in case it helps others.

Not the ideal approach by any means but for those who might gain from it, I created a cron job on another Linux hosting account we had to call the required ASP .NET url. Management horror but does the job.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文