Thread.Sleep引发ThreadAbortException异常
短信平台记录日志模块,是通过异步方式来记录的,即日志工具类里初始化一个Queue对象,公共的写日志方法的处理逻辑是把日志消息放到Queue里。构造器里设定一个死循环,不停的读队,然后把日志消息持久化到磁盘的文本文件里。
构造方法的代码如下:
public Log()
{
//开启线程负责将日志写入到指定地点
ThreadPool.QueueUserWorkItem(o =>
{
try
{
while (true)
{
if (_messageQueue.Count > )
{
lock (_messageQueue)
{
while (_messageQueue.Count > )
{
LogMessage logMessage = _messageQueue.Dequeue();
WriteFile(logMessage);
}
}
}
else
{
Thread.Sleep();
}
}
}
catch (Exception ex)
{
LogMessage log = new LogMessage() { Content = "构造器执行报错:" + ex.ToString() };
FileHelper.WriteFile(string.Format(@"{0}\{1:yyyy-MM-dd}-LOGERROR.txt", _logPath, DateTime.Now), log.GetFormattedLog());
}
});
}
近期通过看线上站点日志,发现不定期会有ThreadAbortException被捕获,
时间:-- ::
构造器执行报错:System.Threading.ThreadAbortException: 正在中止线程。
在 System.Threading.Thread.SleepInternal(Int32 millisecondsTimeout)
在 Common.Log.<.ctor>b__1(Object o)
-------------------------------------------------------------------------------
时间:-- ::
构造器执行报错:System.Threading.ThreadAbortException: 正在中止线程。
在 System.Threading.Thread.SleepInternal(Int32 millisecondsTimeout)
在 Common.Log.<.ctor>b__2(Object o)
----------------------------------------------------------------------------------------
通过分析,当站点应用程序池回收或遇到其他未捕获的异常时,线程会被Abort,这时,当线程里的代码再被执行时,就会抛出ThreadAbortException异常。
微软官方对ThreadAbortException的介绍:
在调用 Abort 方法以销毁线程时,CLR将引发ThreadAbortException。ThreadAbortException 是一种可捕获的特殊异常,但在 catch 块的结尾处它将自动被再次引发。引发此异常时,运行库将在结束线程前执行所有 finally 块。由于线程可以在 finally 块中执行未绑定计算,或调用 Thread.ResetAbort 来取消中止,所以不能保证线程将完全结束。如果您希望一直等到被中止的线程结束,可以调用 Thread.Join 方法。Join 是一个模块化调用,它直到线程实际停止执行时才返回。
下面的示例说明如何中止线程。接收 ThreadAbortException 的线程使用 ResetAbort 方法取消中止请求并继续执行。
using System;
using System.Threading;
using System.Security.Permissions; public class ThreadWork {
public static void DoWork() {
try {
for(int i=; i<; i++) {
Console.WriteLine("Thread - working.");
Thread.Sleep();
}
}
catch(ThreadAbortException e) {
Console.WriteLine("Thread - caught ThreadAbortException - resetting.");
Console.WriteLine("Exception message: {0}", e.Message);
Thread.ResetAbort();
}
Console.WriteLine("Thread - still alive and working.");
Thread.Sleep();
Console.WriteLine("Thread - finished working.");
}
} class ThreadAbortTest {
public static void Main() {
ThreadStart myThreadDelegate = new ThreadStart(ThreadWork.DoWork);
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
Thread.Sleep();
Console.WriteLine("Main - aborting my thread.");
myThread.Abort();
myThread.Join();
Console.WriteLine("Main ending.");
}
}
运行结果:
Thread - working.
Main - aborting my thread.
Thread - caught ThreadAbortException - resetting.
Exception message: Thread was being aborted.
Thread - still alive and working.
Thread - finished working.
Main ending.
————————————————————–我是萌萌哒分界线————————————————————
Thread.Sleep引发ThreadAbortException异常的更多相关文章
- C# Thread.Abort方法与ThreadAbortException异常(取消线程与异常处理)
1.Abort当前线程,后续程序不会执行 class Program { public static Thread thread1; static void Main(string[] args) { ...
- 选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。
异常: 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttribute 标记. 只有将调试器附加到该进程才会引发此异常. ...
- Response.End()出现ThreadAbortException 异常
A. 如果使用 Response.End.Response.Redirect 或 Server.Transfer 方法,将出现 ThreadAbortException 异常.异常内容:由于代码已经过 ...
- c# Clipboard.SetDataObject(bmp1) 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常
c# Clipboard.SetDataObject(bmp1) 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttri ...
- Response.End抛出ThreadAbortException 异常
最近在写程序过程中遇到了一个匪夷所思的错误:Response.End()方法抛出了ThreadAbortException异常,我的代码如下: public void doResponse(){ st ...
- 将不确定变为确定~DateTime.MinValue和MaxValue引发的异常
回到目录 问题描述: SqlDateTime 溢出.必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间 概念相关 .Net中的DateTime结 ...
- WPF控件ComboBox 每个Item的ToolTip引发的异常
介绍 首先介绍下要实现的任务.做一个下拉框,当选择每个项的时候将鼠标发在上面显示该项的ToolTip的内容(Image). 实现 Model: public class SkinInfo : Noti ...
- VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决
VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...
- WPF关于“在“System.Windows.Markup.StaticResourceHolder”上提供值时引发了异常。”问题解决办法
在WPF中添加样式,在MainWindow.xaml使用自定义按钮FButton时报错,报错信息如下: "System.Windows.Markup.XamlParseException&q ...
随机推荐
- PHP常用函数、数组方法
常用函数:rand(); 生成随机数rand(0,50); 范围随机数时间:time(); 取当前时间戳date("Y-m-d H:i:s"); Y:年 m:月份 d:天 H:当前 ...
- python学习 1基础
对象的等于只是对于值而言 函数定义没有变量提升 常用对象 list []: 列表, 排序省空间 tuple (): 元组,一旦初始化不可修改 dict {}: 字典,方便查询 set {}:集合, 值 ...
- MVC5项目中添加Wep API
一.查看MVC版本,决定你有没有必要看这篇文章 打开web.config,看到以下内容 <dependentAssembly> <assemblyIdentity name=&quo ...
- [Leetcode] Contains Duplicate III
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...
- PC端一些非经典兼容性问题小札
IE10默认在input框中输入内容后会显示一个‘X’按钮,方便删除输入的所有内容. 在password输入框显示一个眼睛的按钮,去掉叉叉和眼睛的方法如下: ::-ms-clear { display ...
- Qt下的udp编程
项目需要一个基于udp的客户端, 看着Qt是有个QUdpSocket的类的, 但自带的例子和类的说明都没咋说明白: 怎么用一个QUdpSocket既当发送端, 又当接收端? 谷歌一顿后, 发现很多老内 ...
- 移动端Web适配的两种做法思路总结
看了几篇文章,理一下网易跟淘宝移动端适配的思路,主要是参考 从网易与淘宝的font-size思考前端设计稿与工作流 像素相关概念 物理像素(physical pixel) 一个物理像素是显示器(手机屏 ...
- sqlplus运行sql文件
当sql文件的数据比较多的时候,pl/sql运行比较慢,可以通过oracle的sqlplus进行导入: sqlplus user/password@tnsname@sqlfile.sql; 注意如果文 ...
- ADO.NET数据访问模板整理
/// <summary> /// 数据访问类:hi_test /// </summary> public partial class TestDA { public Test ...
- java.net.ConnectException: Connection timed out
原因可能如下: (1)生成的WSDL的IP地址是不是服务器的IP: (2)代码中是否需要代理,若否,取消代理,若是,设置代理: