博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET的后台Long-Running任务
阅读量:7041 次
发布时间:2019-06-28

本文共 2187 字,大约阅读时间需要 7 分钟。

首先,不推荐在ASP.NET后台中,启动Long-Running的任务。因为无论是用的Task还是ThreadPool.QueueUserWorkItem,ASP.NET不会知道它们在后台运行,这会产生一些问题,比如:

当修改web.config的时候,会触发Appdomain被回收(尽管此时IIS web服务器进程w3wp.exe仍然活着),IIS本身也会每29小时回收应用程序池,这都会导致后台线程被终止,从而引发异常。

当ASP.NET要回收AppDomain,它会让已经存在的请求处理完再回收,ASP.NET和IIS服务器也知道这些请求正在运行,所以等它们完成。问题是ASP.NET不知道任何后台线程比如一个计时器或者其他,它只知道和request相关的操作。

事实上,在后台长时间的运行某些任务实在不是web server该做的事情,通常都可以用其他的方式来避免这样做,比如:

用console application和windows任务管理器,或者使用Windows服务等。

但是,如果确定要这样做,那么在ASP.NET中也有些办法保证后台任务能够安全的退出。

方法一,使用IRegisteredObject接口。

通过IRegisteredObject接口,并且调用HostingEnvironment.RegisterObject方法在ASP.NET中注册它。

当Appdomain要被回收的时候,会调用已注册对象中的IRegisteredObject中的Stop方法。

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

已注册对象没有被取消注册(即没有调用HostingEnvironment.UnregisterObject方法来取消注册),那么Stop方法会被调用两次,第一次调用的时候,immediate参数为false,此时如果已注册对象已经停止了,那么应该调用 HostingEnvironment.UnregisterObject方法来取消注册。如果还不取消注册,那么30秒后,该方法会被再次执行(这是最后的机会),不同的是此时传入的immediate参数为true,此时注册对象必须先调用 UnregisterObject 方法然后返回;否则应用程序管理器将移除该对象的注册。

使用IRegisteredObject接口并不是用来处理后台Long-Running任务的,但是这个功能可以让你安全的退出后台任务。

举个例子,如下:

public class JobHost : IRegisteredObject{    private readonly object _lock = new object();    private bool _shuttingDown;    public JobHost()    {        HostingEnvironment.RegisterObject(this);    }    public void Stop(bool immediate)    {        lock (_lock)        {            _shuttingDown = true;        }        HostingEnvironment.UnregisterObject(this);    }    public void DoWork(Action work)    {        lock (_lock)        {            if (_shuttingDown)            {                return;            }            work();        }    }}

如上面的代码,ASP.NET要回收Appdomain时,Stop 方法会被调用,这个方法会获得一个锁,在DoWork方法也获得同样的所,这样的话,DoWork在运行的时候,Stop方法不得不等待。

方法二,使用HostingEnvironment.QueueBackgroundWorkItem

HostingEnvironment.QueueBackgroundWorkItem 方法在.NET4.5.2中引入,QueueBackgroundWorkItem (QBWI) 通过ASP.NET运行时,注册后台任务。这样的话,由于ASP.NET知道有后台任务,他就不会立即回收Appdomain,当然,这不意味着后台任务可以做任何事情。当ASP.NET需要做回收的时候,它可以通过一个CancellationToken通知后台任务,并且等待30s让工作完成。如果30秒内没问出,那么这个工作也会消失了。关于QueueBackgroundWorkItem的更多细节,可以通过

学习。

方法二,使用HangFire

HangFire是一个开源的类库,提供简单的方法在ASP.NET中执行后台Long-Running任务。这个类库需要一些额外的存储上的支持,SQLServer,Redis或者MSMQ。HangFire的资料在

 

参考资料

转载地址:http://obqal.baihongyu.com/

你可能感兴趣的文章
OpenSSL安装
查看>>
我是如何沉迷于linux系统的?
查看>>
微软正式释出基于 Chromium 的全新版本 Edge
查看>>
Solaris 10 开启SSH
查看>>
我的友情链接
查看>>
iOS支付宝报错 rsa_private read error : private key is NULL
查看>>
给定两个整型变量的值,将两个值的内容进行交换
查看>>
初涉 Git 心得
查看>>
查看系统用户登录信息命令
查看>>
shell 从文件按行读
查看>>
笔记3
查看>>
《Linux菜鸟入门》网关及DNS
查看>>
Python~~简介介绍
查看>>
使用cocoaPods,导入第三方库头文件没有自动联想
查看>>
锁定数据行 for update和for update nowait
查看>>
项目管理工具必须具备的5个功能
查看>>
PHP+socket+SMTP、POP3协议发送、接收邮件
查看>>
我的重构--重构案例2
查看>>
大快网站:如何选择正确的hadoop版本
查看>>
dhcp snopping及华三交换机配置
查看>>