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

本文共 2196 字,大约阅读时间需要 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方法。

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

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

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

举个例子,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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的资料在

 

参考资料

本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/1549947 ,如需转载请自行联系原作者

你可能感兴趣的文章
EXCEL汇总文件信息
查看>>
Vmware vSphere 5.0系列教程之一 Vmware vSphere 5.0简介
查看>>
使用 OpenSSL API 进行安全编程
查看>>
StringBuilder与StringBuffer的比较
查看>>
Puppet-2:Puppet 配置第一个Agent
查看>>
Android 数字签名
查看>>
(已解决)access_token没过期,但已失效的问题{errcode:40001} 微信
查看>>
akka应用状态监控
查看>>
qt-embedd-linux4.8.2编译配置选项说明
查看>>
linux 根据端口查进程
查看>>
Maven pom.xml配置解读
查看>>
SVN clearup提示Path is not a working copy directory
查看>>
15种最佳方式帮你顺利掌握Hadoop技术
查看>>
读写分离
查看>>
emacs+cscope阅读C代码
查看>>
ILGeoNamesSearchController
查看>>
js学习笔记
查看>>
微博舆情监测
查看>>
Flink 幕后之内存管理
查看>>
javascript 学习笔记 【数组操作方法】
查看>>