System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃

时间:2021-03-03 03:32:25

转载:http://www.cnblogs.com/aaa6818162/p/4421305.html

问题现象

IIS应用程序池崩溃(Crash)的特征如下:

1. 从客户端看,浏览器一直处于连接状态,Web服务器无响应。

2. 从服务器端看(Windows Server 2008 + IIS 7.0),在事件日志中会出现Event ID为5010的错误:

A process serving application pool 'q.cnblogs.com' failed to respond to a ping. The process id was '20080'.

这个错误的意思是:IIS检测到程序池'q.cnblogs.com'无响应。为什么没有响应呢?因为程序池'q.cnblogs.com'崩溃了。然后呢?IIS会强制回收应用程序池。

(注:如果在你的Web服务器的事件日志中出现这个错误,一定是某个原因引起了应用程序池崩溃。)

问题原因

我们这次遇到的应用程序池崩溃,是由于在使用System.Threading.Tasks.Task进行异步操作时产生了未处理的异常。

示例代码如下:

System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
Task.Factory.StartNew(() =>
{
//下面的代码未用try..catch捕获异常
//...
});
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃

注:这是一个不需要Callback的异步操作,后续没有task.wait(或者静态方法Task.WaitAll或Task.WaitAny)操作。

当时我们发布程序后,由于Task中代码产生了异常,整个站点无法正常访问,程序池一直处于“崩溃->回收->崩溃->回收”的循环。

解决方法

捕获Task中所有代码的异常,示例代码如下:

System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
Task.Factory.StartNew(() =>
{
try
{
//...
}
catch { }
});
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃

问题分析

在*上提到了这个问题的原因

If you create a Task, and you don't ever call task.Wait() or try to retrieve the result of a Task<T>, when the task is collected by the garbage collector, it will tear down your application during finalization. For details, see MSDN's page on Exception Handling in the TPL.

The best option here is to "handle" the exception.

根据上面的英文,我的理解是:当你创建一个Task,没有调用过task.Wait()或者没有获取它的执行结果,(如果Task中出现了未处理的异常),当这个Task被GC回收时,在GC finalization阶段,会让当前应用程序崩溃。

进一步看MSDN中的Exception Handling (Task Parallel Library)

"Unhandled exceptions that are thrown by user code that is running inside a task are propagated back to the joining thread. ···Exceptions are propagated when you use one of the static or instance Task.Wait or Task(Of TResult).Wait methods···"

翻译:在一个task中运行的代码抛出的未处理异常会被回传给(创建该task的)主线程。···当你调用Task.Wait时,异常才会被回传(给主线程)。

分析:当我们遇到的情况是没调用Task.Wait,也就是异常没有被回传给主线程。下面的这句就提到了这个:

"If you do not wait on a task that propagates an exception, or access its Exception property, the exception is escalated according to the .NET exception policy when the task is garbage-collected."

译:如果你在一个task中没有等待异常被传播,或者访问它的异步特性,在task被GC回收时,该异常会遵循.NET异常策略被逐步升级。

分析:逐步升级的后果就是当前应用程序进程崩溃,对于ASP.NET程序来说,就是应用程序池崩溃。

进一步的解决方法

MSDN上的推荐做法是用Task.ContinueWith观察Task中抛出的异常并进行处理,示例代码如下:

System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
var task1 = Task.Factory.StartNew(() =>
{
throw new MyCustomException("Task1 faulted.");
})
.ContinueWith((t) =>
{
Console.WriteLine("I have observed a {0}",
t.Exception.InnerException.GetType().Name);
},
TaskContinuationOptions.OnlyOnFaulted);
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃

小结

应用程序池崩溃的原因总结 —— System.Threading.Tasks.Task中的代码抛出了未处理的异常,由于没有Task.Wait()操作,异常没有被回传给主线程,在GC回收时,发现这个身份不明的异常。然后,这个异常被一级一级上报,直到当前程序进程的最高领导,最高领导为了顾全大局,果然决定与这个异常同归于尽,也就是让整个应用程序池崩溃。。。

System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃的更多相关文章

  1. System&period;Threading&period;Tasks&period;Task 引起的 IIS 应用池崩溃

    接口服务运行一段时间后,IIS应用池就会突然挂掉,事件查看日志,会有事件日志Event ID为5011的错误 为应用程序池“PokeIn”提供服务的进程在与 Windows Process Activ ...

  2. System&period;Threading&period;Tasks&period;Task引起的IIS应用程序池崩溃

    问题现象 IIS应用程序池崩溃(Crash)的特征如下: 1. 从客户端看,浏览器一直处于连接状态,Web服务器无响应. 2. 从服务器端看(Windows Server 2008 + IIS 7.0 ...

  3. Threading&period;Tasks&period;Task多线程 静态全局变量&lpar;字典&rpar; --只为了记录

    --------------------------------------------------------------后台代码---------------------------------- ...

  4. &period;Net多线程编程—System&period;Threading&period;Tasks&period;Parallel

    System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...

  5. HttpClient exception&colon;ExceptionType&colon;System&period;Threading&period;Tasks&period;TaskCanceledException&colon; The operation was canceled&period; ---&gt&semi; System&period;IO&period;IOException&colon; Unable to read data from the transport connection&colon; Operation ca

    error msg: System.Threading.Tasks.TaskCanceledException: The operation was canceled. ---> System. ...

  6. 转载 Net多线程编程—System&period;Threading&period;Tasks&period;Parallel

    .Net多线程编程—System.Threading.Tasks.Parallel   System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Paral ...

  7. 一、并行编程 - 数据并行 System&period;Threading&period;Tasks&period;Parallel 类

    一.并行概念 1.并行编程 在.NET 4中的并行编程是依赖Task Parallel Library(后面简称为TPL) 实现的.在TPL中,最基本的执行单元是task(中文可以理解为"任 ...

  8. System&period;Threading&period;Tasks

    前言: 我们之前介绍了两种构建多线程软件的编程技术(使用异步委托或通过System.Threading的成员).这两个可以在任何版本的.NET平台工作. 关于System.Threading 的介绍 ...

  9. &period;NET 4&period;0 System&period;Threading&period;Tasks学习笔记

    由于工作上的需要,学习使用了System.Threading.Tasks的使用,特此笔记下来. System.Threading.Tasks的作用: Tasks命名空间下的类试图使用任务的概念来解决线 ...

随机推荐

  1. Vs2012编写C语言

    本来我也是用VC++6.0编写C语言的,但是由于这个版本过老并且和win7,win8,win10的不兼容所以去下载了vs2012,一开始的时候不知道怎么用,现在学会了就写一个教程分享一下. 这时就遇到 ...

  2. 使用archiver在nodejs下打包

    archiver是一个在nodejs中能跨平台实现打包功能的模块,可以打zip和tar包,是一个比较好用的三方模块. 使用前先安装archiver模块. npm install archiver 建立 ...

  3. coursera机器学习笔记-机器学习概论,梯度下降法

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  4. 实用的Bootstrap的扩展和插件集合

    bootstrap插件 http://www.missyuan.net/school/other_2014/other_16472.html http://www.oschina.net/news/5 ...

  5. C&num;泛型集合之Dictionary&lt&semi;k&comma; v&gt&semi;使用技巧

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...

  6. 【前端】&colon;Dom

    前言: 昨天写了篇关于JavaScript的,今天写篇Dom的(插入4个实例),写完之后感觉知识点还不少~ 内容当然会用到[前端]:JavaScript的知识.下篇博客会写关于jQuery~~ 一.D ...

  7. Verilog HDL的程序结构及其描述

    这篇博文是写给要入门Verilog HDL及其初学者的,也算是我对Verilog  HDL学习的一个总结,主要是Verilog HDL的程序结构及其描述,如果有错,欢迎评论指出. 一.Verilog ...

  8. MD5加密Util

    目录 (1)需要导入的包 (2)MD5Util类 (3)使用举例 (1)需要导入的包 <dependency> <groupId>org.apache.commons</ ...

  9. ABP框架系列之三:&lpar;Entity Framework Integration-实体框架集成&rpar;

    ASP.NET Boilerplate can work with any O/RM framework. It has built-in integration with EntityFramewo ...

  10. mysql 存储引擎对索引的支持

    一.首先给出mysql官方文档给出的不同存储引擎对索引的支持 从上面的图中可以得知,mysql 是支持hash索引的,但支持和不支持又和具体的存储引擎有关系.从图中看到InnoDB是支持Btree索引 ...