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

在这时、我们可以通过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. android recyclerview 更新ui

    http://blog.csdn.net/leejizhou/article/details/51179233

  2. RABBITMQ/JAVA (主题)

    上篇博文中,我们进一步改良了日志系统.即使用Direct类型的转换器,使得接受者有能力进行选择性的接收日志,而非fanout那样,只能够无脑的转发. 虽然使用Direct类型的转换器改进了日志系统.但 ...

  3. c/c++ 函数指针 指针函数 数组的引用 指针数组 数组指针

    1.指针数组数组指针 引用数组 数组的引用 int *a[10] 指针数组 每一个元素都是一个指针 Int (*a)[10] 数组指针 P指向一个含有10个元素的数组 Int (&a)[10] ...

  4. js中Dom对象的position属性

    首先应该明白什么是流?这个估计也很容易明白,我就不说了.顺便说下,float设置了这个属性就暂时脱离了流的存在,clear后才会到流里面. position:absolute| fixed | rel ...

  5. 巧用TexturePacker命令行

    游戏开发使用TexturePacker来生成图片的atlas sheet, 工具非常好用. 一般GUI的方法, 新建一个tps文件, 将要图片加载进来,调整参数和输出路径, 最后点publish. 在 ...

  6. pyhton 27 pip命令无法使用 没有Scripts文件夹 的解决方法

    1 安装了setuptools http://jingyan.baidu.com/article/fb48e8be52f3166e622e1400.html 2 用ez_setup.py安装了setu ...

  7. 机器学习(一) 从一个R语言案例学线性回归

    写在前面的话 按照正常的顺序,本文应该先讲一些线性回归的基本概念,比如什么叫线性回归,线性回规的常用解法等.但既然本文名为<从一个R语言案例学会线性回归>,那就更重视如何使用R语言去解决线 ...

  8. Spring总结

    此君也是使用过多时了,却从来没有系统的总结过 以下,弥补,盼不晚: Spring为什么是框架&容器 1.框架的原因: 其提供多个组件的搭建,和支持其他事务事件,符合框架定义 ps:什么是框架呢 ...

  9. canvas实现类似弹窗广告效果

    先看看下面的效果图,想想使用canvas是怎样实现的? 如下图: 这个就不详细描述了,看代码就会了. <!doctype html> <html lang="en" ...

  10. D3 的优势

    可视化的库有很多,基于 JavaScript 开发的库也有很多,D3 有什么优势呢? (1)数据能够与 DOM 绑定在一起 D3 能够将数据与 DOM 绑定在一起,使得数据与图形成为一个整体,即图形中 ...