转 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时间已到.在操作完成之间超 ...
随机推荐
- libdispatch for Linux
这个Dispatch是苹果的一个高效的处理库,它在ubuntu上的安装如下: Build/Runtime Requirements 如下: libBlocksRuntime libpthread_wo ...
- MySQL高可用之MHA搭建
测试环境 节点1 172.16.200.231 6666 master 节点2 172.16.200.27 6666 slave1 ...
- Notes of learning AutoLayout
在XCode5中,如果我们添加一个Button或者Label,或者其他的什么标准View,而不设置任何constraints,IB会自动生成constraints,而这些constraints是fix ...
- cassandra中对节点失败与否的探测方法, the Phi accrual Failure Dector,附论文
(1)在分布式系统中,对于某个节点是否还“活着”的探测,通常是设定一个时间的阀值,然后根据接收到的“心跳”信息的间隔,来判定这个节点是否还活着,然后返回一个bool值: 但这种做法很容易造成误判:因为 ...
- jQuery里ajax的用法
$.ajax({ type:'post',//这里页面数据发送请求的方式可以为post和get cache:'false ', //这里可以为false或者true 是否要缓存 ,默认为false u ...
- jQuery 中 offset()方法与用position()的区别
jq中offset().left和offset().top获取的是相对于整个文档左上角的偏移. 而用$(selector).position().left和.top 取到的则是相对于selector父 ...
- 动态添加Marquee标签,并动态赋值与属性
前台加载js $(function(){ var publishStr="<%=publishText%>" var marqueeStr=" <mar ...
- Array函数
array_flip()例子 , , "c" );$trans = array_flip($trans);print_r($trans);?> 答案: Array ( [1] ...
- java文件下载
/** * zip 导出 * @param response * @param zipName * @throws Exception */ private void outZip(HttpServl ...
- iOS红马甲项目Bug总结(2)
背景:iOS调用相机和访问图库 一.调用相机或图库: -(void)imgviewClick { ALAuthorizationStatus author = [ALAssetsLibrary aut ...