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

在这时、我们可以通过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. String类实现

    String类是应用框架中不可或缺的类 重载运算符实现字符串的操作 #idndef IOTECK_STRING_H_#define IOTECK_STRING_H_namespace iotek{ c ...

  2. 新手入门之GDB调试

    写这篇文章算是对最近两天工作的一个经验总结吧. 要让可执行文件比较方便地在DGB上调试,在用gcc编译的时候要使用-g选项. 如何使用GDB启动被调试程序? "gdb path_to_deb ...

  3. OC之160728

    NSData与NSMutableData:代表数据缓冲区有两个作用,将数据读入NSData和输出NSData数据 输出 将字符串写入指定文件 用NSFileManager:为创建,删除,移动,复制文件 ...

  4. OrCAD搭建Access数据库

    刚进入到一个小公司,接到的第一个电路设计的案子是从零开始的,辛苦就不说,关键是这么不严谨,容易出错,于是乎,问题来了,能否从零开始着手建立个类似于以前公司的数据库,管理原理图封装,PCB封装及规格书! ...

  5. 在VS下使用 GitFlow管理项目开发

    在VS下使用 GitFlow管理项目开发 1.右键将你的解决方案添加到源代码管理,如果你的VS没有安装git,会提示安装,安装完成之后,在团队资源管理可以看到如下界面 (图一) 2.安装gitflow ...

  6. 高通CP Crash分析调试

    1. 转换tlcore文件 获取 EBICS0.BIN tl2elf --qconly tlcore 2.使用T32 命令把Riva的dump信息从EBICS0文件分离出来 data.load.BIN ...

  7. Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?

    How to block a fake DHCP server without enabling DHCP snooping? Scenario How to block a fake DHCP se ...

  8. 多线程、多进程、协程、缓存(memcache、redis)

    本节内容: 线程: a:基本的使用: 创建线程: 1:方法 import threading def f1(x): print(x) if __name__=='__main__': t=thread ...

  9. Oracle创建、删除表空间、用户

    1.创建临时表空间 create temporary tablespace linshi tempfile 'e:\linshi.dbf' size 50m autoextend on next 50 ...

  10. java SpringUtil获取bean

    package com.whaty.framework.common.spring; import java.io.PrintStream; import org.springframework.be ...