转 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时间已到.在操作完成之间超 ...
随机推荐
- python 从文件导入分类
# -*- coding:utf-8 -*- """ 从文件导入分类 根据行首制表符或空格确定层级关系(4个空格等于一个制表符 同一行制表符和空格不能混用 ) 必须是 u ...
- android布局学习之相对布局(RelativeLayout)
移通152余继彪 RelativeLayout可以设置某一个视图相对于其他视图的位置,这些位置可以包括上下左右等 RelativeLayout 属性 说明 android:layout_bel ...
- IOS演变史
我是从iOS5开始接触iPhone操作系统,对此系统也算是有爱有恨,今天从网上整理以下整个iOS发展的历史,了解了解也算做以后闲时讨论的一个话题. 电脑需要操作系统,手机也需要,2007年,苹果带着旗 ...
- 北大poj-1088
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 88484 Accepted: 33177 Description ...
- Python学习路程day1
变量起名: 变量名如果太长,推荐使用下划线来分开,让人看得清晰明白.例:nums_of_alex_girl=19 .或者是驼峰写法,即首字母大写.例:NumOfAlexGf=18 注意:不合法的变量起 ...
- linux命令:more
1.命令介绍: more用来逐页输出文件内容,空格键进入到下一页,b键返回到上一页. 2.命令格式: more [选项] 文件 3.命令参数 +n 从笫n行开始显示 -n 定义屏 ...
- 搜索栏会消失 uisearchbar 狂点消失的问题解决
经过反复试验和错误很多,我发现当searchdisplaycontroller结束搜索,搜索栏会消失,所以我重新插入到搜索栏表头和它为我工作. - (void)searchDisplayControl ...
- 第三个Sprint冲刺第七天
讨论地点:宿舍 讨论成员:邵家文.李新.朱浩龙.陈俊金 讨论问题:做最后的工作
- 如何让LinearLayout也有类似Button的点击效果?
有的时候,我们希望LinearLayout布局也有点击的效果,这时候我们不仅需要一个作为背景的selector,还要设置一些其它属性才行: android:clickable="true&q ...
- Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)
什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定). 这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户 ...