在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死。

在这时、我们可以通过Thread、Thread + Invoke(UI)或者是 delegate.BeginInvoke 来避免界面假死,

但是这样做时,某些代码或者是某个方法的执行超时的时间还是无法操控的。 那么我们又是否有一种比较通用的方法、来设定某一个方法的执行超时的时间,让该其一旦超过指定时间则跳出指定方法、进而继续向下执行呢?

答案当然是肯定的。

delegate.BeginInvoke可以实现代码代码的异步执行,在这种情况下,只要让程序可以等待一个Timespan,如果在Timespan到达之前方法内的代码还没有执行完毕、说明该方法执行超时了。

那么关键的就是“等待一个Timespan”,而恰好.NET 里提供了一些类和方法来实现该功能。我这里选用的是ManualResetEvent.WaitOne(timespan, false);其返回值代码其是否在特定时间内收到信号,而我们恰好可以利用这个布尔值 外加一个标记变量 来判断一个方法是否执行超时。

相关的实现代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. namespace Common
  7. {
  8. public delegate void DoHandler();
  9. public class Timeout
  10. {
  11. private ManualResetEvent mTimeoutObject;
  12. //标记变量
  13. private bool mBoTimeout;
  14. public DoHandler Do;
  15. public Timeout()
  16. {
  17. //  初始状态为 停止
  18. this.mTimeoutObject = new ManualResetEvent(true);
  19. }
  20. ///<summary>
  21. /// 指定超时时间 异步执行某个方法
  22. ///</summary>
  23. ///<returns>执行 是否超时</returns>
  24. public bool DoWithTimeout(TimeSpan timeSpan)
  25. {
  26. if (this.Do == null)
  27. {
  28. return false;
  29. }
  30. this.mTimeoutObject.Reset();
  31. this.mBoTimeout = true; //标记
  32. this.Do.BeginInvoke(DoAsyncCallBack, null);
  33. // 等待 信号Set
  34. if (!this.mTimeoutObject.WaitOne(timeSpan, false))
  35. {
  36. this.mBoTimeout = true;
  37. }
  38. return this.mBoTimeout;
  39. }
  40. ///<summary>
  41. /// 异步委托 回调函数
  42. ///</summary>
  43. ///<param name="result"></param>
  44. private void DoAsyncCallBack(IAsyncResult result)
  45. {
  46. try
  47. {
  48. this.Do.EndInvoke(result);
  49. // 指示方法的执行未超时
  50. this.mBoTimeout = false;
  51. }
  52. catch (Exception ex)
  53. {
  54. Console.WriteLine(ex.Message);
  55. this.mBoTimeout = true;
  56. }
  57. finally
  58. {
  59. this.mTimeoutObject.Set();
  60. }
  61. }
  62. }
  63. }
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();
}
}
}
}

测试代码如下:

  1. class Program
  2. {
  3. privatestatic Stopwatch watch;
  4. privatestatic System.Threading.Timer timer;
  5. [STAThread]
  6. staticvoid Main(string[] args)
  7. {
  8. watch =new Stopwatch();
  9. Timeout timeout =new Timeout();
  10. timeout.Do =new Program().DoSomething;
  11. watch.Start();
  12. timer =new System.Threading.Timer(timerCallBack, null, 0, 500);
  13. Console.WriteLine("4秒超时开始执行");
  14. bool bo = timeout.DoWithTimeout(new TimeSpan(0, 0, 0, 4));
  15. Console.WriteLine(string.Format("4秒超时执行结果,是否超时:{0}", bo));
  16. Console.WriteLine("***************************************************");
  17. timeout =new Timeout();
  18. timeout.Do =new Program().DoSomething;
  19. Console.WriteLine("6秒超时开始执行");
  20. bo = timeout.DoWithTimeout(new TimeSpan(0, 0, 0, 6));
  21. Console.WriteLine(string.Format("6秒超时执行结果,是否超时:{0}", bo));
  22. timerCallBack(null);
  23. watch.Stop();
  24. timer.Dispose();
  25. Console.ReadLine();
  26. }
  27. staticvoid timerCallBack(object obj)
  28. {
  29. Console.WriteLine(string.Format("运行时间:{0}秒", watch.Elapsed.TotalSeconds.ToString("F2")));
  30. }
  31. publicvoid DoSomething()
  32. {
  33. // 休眠 5秒
  34. System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, 5));
  35. }
  36. }

原文地址 http://blog.csdn.net/educast/article/details/7430932

转 C# 给某个方法设定执行超时时间的更多相关文章

  1. C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)

    我自己写的 /// <summary> /// 函数运行超时则终止执行(超时则返回true,否则返回false) /// </summary> /// <typepara ...

  2. C# 给某个方法设定执行超时时间

    ManualResetEvent.WaitOne 方法 https://msdn.microsoft.com/en-us/library/system.threading.manualreseteve ...

  3. C# 给某个方法设定执行超时时间-2

    var response = RunTaskWithTimeout<ReturnType>( (Func<ReturnType>)); /// <summary> ...

  4. Java基础知识强化之网络编程笔记25:Android网络通信之 Future接口介绍(Java程序执行超时)

    1. Future接口简介 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API ...

  5. Java程序执行超时——Future接口介绍

    在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API的一部分,在java.uti ...

  6. [C#.net]SqlDataAdapter 执行超时已过期 完成操作之前已超时或服务器未响应

    随着数据库数据的不断增大,查询时间也随之增长.而客户端与数据库连接时间以及命令的执行时间都是有限的.默认为30s.所以在查询数据的时候,程序会出现 “超时时间已到.在操作完成之前超时时间已过或服务器未 ...

  7. 关于PHP执行超时的问题

    PHP配置文件的参数max_execution_time表示脚本执行超时时间 max_execution_time=0表示不限制 max_execution_time=2表示执行两秒后终止,同时报错F ...

  8. timeout Timeout时间已到.在操作完成之前超时时间已过或服务器未响应

    Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超 ...

  9. (摘)timeout Timeout时间已到.在操作完成之前超时时间已过或服务器未响应的几种情况

    Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超 ...

随机推荐

  1. Windows 下java环境变量的配置(Windows7 ,8,8.1,10)

    Windows 下java环境变量的配置 在“系统”面板的左上角选择“高级系统设置”,在弹出的系统属性中选择”高级“项,然后点击右下角的“环境变量(N)...”,就此进入JAVA环境变量的配置. 如果 ...

  2. 配置ConvenientBanner时出现的问题

    ConvenientBanner: compile 'com.bigkoo:convenientbanner:2.0.5' 找不到依赖库 classpath 'com.jfrog.bintray.gr ...

  3. HBase的快照技术

    (1)     什么是快照 快照就是一份元信息的合集,允许管理员恢复到表的先前状态,快照不是表的复制而是一个文件名称列表,因而不会复制数据. 完全快照恢复是指恢复到之前的表结构以及当时的数据快照之后发 ...

  4. How To Use Hbase Bulk Loading

    最近在学习hbase,学到利用如何将数据导入到hbase中,采用的方式是批量导入:bulk load的方法,中间出现了一些问题,下面将执行的步骤记录一下,以供日后查阅: 说明:导入的方式是将csv文件 ...

  5. UE4 异步资源加载

    http://blog.csdn.net/pizi0475/article/details/48178861 http://blog.sina.com.cn/s/blog_710ea1400102vl ...

  6. HDU 4768 (二分区间---涨姿势)

    题意:告诉n组A,B,C,按照A + k * C生成等差数列,问这n组数列中哪个数字出现了奇数次以及出现了几次,题目保证最多只会出现一个这种数字. 分析:读完题并没有思路,后来知道是二分区间,枚举是哪 ...

  7. codeforces 682C Alyona and the Tree(DFS)

    题目链接:http://codeforces.com/problemset/problem/682/C 题意:如果点v在点u的子树上且dist(u,v)>a[v]则u和其整个子树都将被删去,求被 ...

  8. 大数据批量插入数据库使用(SqlBulkCopy )效率更高

    SqlBulkCopy类是System.Data.SqlClient下的类,我们开发中不常用,甚至不知道有这么一个类的存在,但确实比sql插入,事务批量插入,sql批量拼接插入快很多,比调用存储过程插 ...

  9. Node.js高级编程读书笔记 - 6 应用程序构建和调试 - Never

    Explanation 现阶段console.log(...),util.inspect(...), JSON.stringify(...)在控制台输出已经够用了[2015/07/19]. 单元测试隶 ...

  10. select 通过jq赋值

    <select name="F_YSBAQLX" onchange="selectvalue()" id="lista" prompt ...