一种利用线程池线程执行任务, 并能够结束超时任务的方法 (.NET实现)
来源:互联网 发布:佳驰软件 编辑:程序博客网 时间:2024/04/30 14:21
背景:
前些日子写了一个利用正则表达式来提取内容的程序,要求正则表达式可以灵活地配置,但事后在运行时发现一个问题:有的正则表达式写的效率低下,将CPU占用了100%,并且执行了很长时间也没有执行完,影响了其它任务的工作.于是想把执行正则表达式的代码放在一个可以在超时时自动中断的函数中.
首先想到的是每次使用线程System.Threading.Thread来定义一个新的线程,启动并执行,然后用ManualResetEvent等待它执行一段指定的时间,如果没有执行完,则调用该线程的Abort来中断它.
但大多数正则表达式执行的效率很高,这样每次都开一个线程会影响效率,于是想到了利用线程池线程来执行它,但在这儿遇到了难题,线程池线程只有在运行的时候才会利用Thread.CurrentThread来获得当前的线程(以便在超时时调用它的Abort方法),.
这种做法是很危险的时候,可能在超时之后,当我们调用Abort方法的那一瞬间,该线程已经完成了执行,并且又在执行其它任务了,于是中断了不该中断的任务.
思前想后,想到了利用两个ManualResetEvent来保证不在Abort时中断其它任务的方法:
代码:
delegate void Delegate();
/// <summary>
/// 执行指定的方法,如果在指定的时间之内没有完成,则中止
/// </summary>
/// <param name="func">任务过程</param>
/// <param name="timeSpan">超时时间</param>
/// <param name="timeoutCallback">如果超时,则调用该方法</param>
/// <returns>是否正确执行完毕</returns>
public static bool Call(Delegate func, TimeSpan timeSpan, Delegate timeoutCallback)
{
if (func == null)
throw new ArgumentNullException("func");
ManualResetEvent resetEvent = new ManualResetEvent(false);
ManualResetEvent waitThreadEvent = new ManualResetEvent(false);
Exception error = null;
Thread thread = null;
// 将任务加到线程当中
ThreadPool.QueueUserWorkItem(delegate {
thread = Thread.CurrentThread;
try { func(); }
catch (ThreadAbortException) { }
catch (Exception ex) { error = ex; }
resetEvent.Set();
waitThreadEvent.WaitOne(); // 每次线程执行结束都等待后续的处理逻辑
});
try
{
bool result = resetEvent.WaitOne(timeSpan, false); // 等待任务的结束
if (error != null) // 说明在执行过程中出现异常,直接抛出异常
throw error;
if (!result)
{
if (thread != null)
{
thread.Abort(); // 此时可以确保该线程没有开始运行新的任务
waitThreadEvent.Set();
}
if (timeoutCallback != null)
timeoutCallback();
}
return result;
}
finally
{
waitThreadEvent.Set(); // 最后确保释放线程池线程
}
}
- 一种利用线程池线程执行任务, 并能够结束超时任务的方法 (.NET实现)
- 线程任务超时结束方法
- Java多线程任务超时结束的5种实现方法
- Java多线程任务超时结束的5种实现方法
- java利用线程池(ExecutorService)配合Callable和Future实现执行方法超时的阻断
- 线程实现定时执行任务
- 线程池任务执行流程
- Spring线程池执行任务
- 多线程线程池控制一个方法的并发量 限制只有5个线程执行任务
- 在Android UI线程中执行定时任务的方法
- 开启线程池 加入任务 传入参数 此任务能够在执行完成时得到返回值
- 周期性任务执行实现模板线程类
- 单线程实现定时执行任务功能
- 利用任务线程创建进度对话框的方法
- 一种处理多任务的线程池设计
- 利用线程消息队列,实现任务队列
- java线程池之ThreadPoolExecutor(三):提交任务并得到任务执行结果
- 两个带有线程池的方法分别执行两组线程任务,第二个方法需要等待第一组任务执行完毕
- 开博第一篇
- tomcat 基本配置
- 小爷正当年少时,等你十年又何妨!
- excel转换成指定格式的文件
- freemarker
- 一种利用线程池线程执行任务, 并能够结束超时任务的方法 (.NET实现)
- 简单菜谱
- 基于自然语言对话的智能辅导系统
- 股市交易教训。
- 关于关闭事件跟踪程序
- [3-25]上午沪、深收盘总结
- 进程隐藏的两种方法(转)
- 看到两个写的很好的关于字符集,编码的文章,推荐大家看看,另外纠正了一下原文中的小bug(UTF-8 UniCode UTF-16 UCS 等)
- Emacs 学习总结