转 C# 给某个方法设定执行超时时间
在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死。
在这时、我们可以通过Thread、Thread + Invoke(UI)或者是 delegate.BeginInvoke 来避免界面假死,
但是这样做时,某些代码或者是某个方法的执行超时的时间还是无法操控的。 那么我们又是否有一种比较通用的方法、来设定某一个方法的执行超时的时间,让该其一旦超过指定时间则跳出指定方法、进而继续向下执行呢?
答案当然是肯定的。
delegate.BeginInvoke可以实现代码代码的异步执行,在这种情况下,只要让程序可以等待一个Timespan,如果在Timespan到达之前方法内的代码还没有执行完毕、说明该方法执行超时了。
那么关键的就是“等待一个Timespan”,而恰好.NET 里提供了一些类和方法来实现该功能。我这里选用的是ManualResetEvent.WaitOne(timespan, false);其返回值代码其是否在特定时间内收到信号,而我们恰好可以利用这个布尔值 外加一个标记变量 来判断一个方法是否执行超时。
相关的实现代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- namespace Common
- {
- public delegate void DoHandler();
- public class Timeout
- {
- private ManualResetEvent mTimeoutObject;
- //标记变量
- private bool mBoTimeout;
- public DoHandler Do;
- public Timeout()
- {
- // 初始状态为 停止
- this.mTimeoutObject = new ManualResetEvent(true);
- }
- ///<summary>
- /// 指定超时时间 异步执行某个方法
- ///</summary>
- ///<returns>执行 是否超时</returns>
- public bool DoWithTimeout(TimeSpan timeSpan)
- {
- if (this.Do == null)
- {
- return false;
- }
- this.mTimeoutObject.Reset();
- this.mBoTimeout = true; //标记
- this.Do.BeginInvoke(DoAsyncCallBack, null);
- // 等待 信号Set
- if (!this.mTimeoutObject.WaitOne(timeSpan, false))
- {
- this.mBoTimeout = true;
- }
- return this.mBoTimeout;
- }
- ///<summary>
- /// 异步委托 回调函数
- ///</summary>
- ///<param name="result"></param>
- private void DoAsyncCallBack(IAsyncResult result)
- {
- try
- {
- this.Do.EndInvoke(result);
- // 指示方法的执行未超时
- this.mBoTimeout = false;
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- this.mBoTimeout = true;
- }
- finally
- {
- this.mTimeoutObject.Set();
- }
- }
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace Common
{
public delegate void DoHandler(); public class Timeout
{
private ManualResetEvent mTimeoutObject;
//标记变量
private bool mBoTimeout; public DoHandler Do; public Timeout()
{
// 初始状态为 停止
this.mTimeoutObject = new ManualResetEvent(true);
}
///<summary>
/// 指定超时时间 异步执行某个方法
///</summary>
///<returns>执行 是否超时</returns>
public bool DoWithTimeout(TimeSpan timeSpan)
{
if (this.Do == null)
{
return false;
}
this.mTimeoutObject.Reset();
this.mBoTimeout = true; //标记
this.Do.BeginInvoke(DoAsyncCallBack, null);
// 等待 信号Set
if (!this.mTimeoutObject.WaitOne(timeSpan, false))
{
this.mBoTimeout = true;
}
return this.mBoTimeout;
}
///<summary>
/// 异步委托 回调函数
///</summary>
///<param name="result"></param>
private void DoAsyncCallBack(IAsyncResult result)
{
try
{
this.Do.EndInvoke(result);
// 指示方法的执行未超时
this.mBoTimeout = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
this.mBoTimeout = true;
}
finally
{
this.mTimeoutObject.Set();
}
}
}
}
测试代码如下:
- class Program
- {
- privatestatic Stopwatch watch;
- privatestatic System.Threading.Timer timer;
- [STAThread]
- staticvoid Main(string[] args)
- {
- watch =new Stopwatch();
- Timeout timeout =new Timeout();
- timeout.Do =new Program().DoSomething;
- watch.Start();
- timer =new System.Threading.Timer(timerCallBack, null, 0, 500);
- Console.WriteLine("4秒超时开始执行");
- bool bo = timeout.DoWithTimeout(new TimeSpan(0, 0, 0, 4));
- Console.WriteLine(string.Format("4秒超时执行结果,是否超时:{0}", bo));
- Console.WriteLine("***************************************************");
- timeout =new Timeout();
- timeout.Do =new Program().DoSomething;
- Console.WriteLine("6秒超时开始执行");
- bo = timeout.DoWithTimeout(new TimeSpan(0, 0, 0, 6));
- Console.WriteLine(string.Format("6秒超时执行结果,是否超时:{0}", bo));
- timerCallBack(null);
- watch.Stop();
- timer.Dispose();
- Console.ReadLine();
- }
- staticvoid timerCallBack(object obj)
- {
- Console.WriteLine(string.Format("运行时间:{0}秒", watch.Elapsed.TotalSeconds.ToString("F2")));
- }
- publicvoid DoSomething()
- {
- // 休眠 5秒
- System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, 5));
- }
- }
转 C# 给某个方法设定执行超时时间的更多相关文章
- C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)
我自己写的 /// <summary> /// 函数运行超时则终止执行(超时则返回true,否则返回false) /// </summary> /// <typepara ...
- C# 给某个方法设定执行超时时间
ManualResetEvent.WaitOne 方法 https://msdn.microsoft.com/en-us/library/system.threading.manualreseteve ...
- C# 给某个方法设定执行超时时间-2
var response = RunTaskWithTimeout<ReturnType>( (Func<ReturnType>)); /// <summary> ...
- Java基础知识强化之网络编程笔记25:Android网络通信之 Future接口介绍(Java程序执行超时)
1. Future接口简介 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API ...
- Java程序执行超时——Future接口介绍
在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API的一部分,在java.uti ...
- [C#.net]SqlDataAdapter 执行超时已过期 完成操作之前已超时或服务器未响应
随着数据库数据的不断增大,查询时间也随之增长.而客户端与数据库连接时间以及命令的执行时间都是有限的.默认为30s.所以在查询数据的时候,程序会出现 “超时时间已到.在操作完成之前超时时间已过或服务器未 ...
- 关于PHP执行超时的问题
PHP配置文件的参数max_execution_time表示脚本执行超时时间 max_execution_time=0表示不限制 max_execution_time=2表示执行两秒后终止,同时报错F ...
- timeout Timeout时间已到.在操作完成之前超时时间已过或服务器未响应
Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超 ...
- (摘)timeout Timeout时间已到.在操作完成之前超时时间已过或服务器未响应的几种情况
Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超 ...
随机推荐
- Windows 下java环境变量的配置(Windows7 ,8,8.1,10)
Windows 下java环境变量的配置 在“系统”面板的左上角选择“高级系统设置”,在弹出的系统属性中选择”高级“项,然后点击右下角的“环境变量(N)...”,就此进入JAVA环境变量的配置. 如果 ...
- 配置ConvenientBanner时出现的问题
ConvenientBanner: compile 'com.bigkoo:convenientbanner:2.0.5' 找不到依赖库 classpath 'com.jfrog.bintray.gr ...
- HBase的快照技术
(1) 什么是快照 快照就是一份元信息的合集,允许管理员恢复到表的先前状态,快照不是表的复制而是一个文件名称列表,因而不会复制数据. 完全快照恢复是指恢复到之前的表结构以及当时的数据快照之后发 ...
- How To Use Hbase Bulk Loading
最近在学习hbase,学到利用如何将数据导入到hbase中,采用的方式是批量导入:bulk load的方法,中间出现了一些问题,下面将执行的步骤记录一下,以供日后查阅: 说明:导入的方式是将csv文件 ...
- UE4 异步资源加载
http://blog.csdn.net/pizi0475/article/details/48178861 http://blog.sina.com.cn/s/blog_710ea1400102vl ...
- HDU 4768 (二分区间---涨姿势)
题意:告诉n组A,B,C,按照A + k * C生成等差数列,问这n组数列中哪个数字出现了奇数次以及出现了几次,题目保证最多只会出现一个这种数字. 分析:读完题并没有思路,后来知道是二分区间,枚举是哪 ...
- codeforces 682C Alyona and the Tree(DFS)
题目链接:http://codeforces.com/problemset/problem/682/C 题意:如果点v在点u的子树上且dist(u,v)>a[v]则u和其整个子树都将被删去,求被 ...
- 大数据批量插入数据库使用(SqlBulkCopy )效率更高
SqlBulkCopy类是System.Data.SqlClient下的类,我们开发中不常用,甚至不知道有这么一个类的存在,但确实比sql插入,事务批量插入,sql批量拼接插入快很多,比调用存储过程插 ...
- Node.js高级编程读书笔记 - 6 应用程序构建和调试 - Never
Explanation 现阶段console.log(...),util.inspect(...), JSON.stringify(...)在控制台输出已经够用了[2015/07/19]. 单元测试隶 ...
- select 通过jq赋值
<select name="F_YSBAQLX" onchange="selectvalue()" id="lista" prompt ...