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

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

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

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

答案当然是肯定的。

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

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

相关的实现代码如下:

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();
            }
        }
    }

调用:

private static Stopwatch watch;
        private static System.Threading.Timer timer;

        static void 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();
        }
        static void timerCallBack(object obj)
        {
            Console.WriteLine(string.Format("运行时间:{0}秒", watch.Elapsed.TotalSeconds.ToString("F2")));
        }
        public void DoSomething()
        {
            // 休眠 5秒
            System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, 5));
        }

地址:http://www.cnblogs.com/08shiyan/archive/2011/07/30/2122183.html

时间: 2024-09-30 10:55:24

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

C# 给某个方法设定执行超时时间 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)

在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死. 在这时.我们可以通过Thread.Thread + Invoke(UI)或者是 delegate.BeginInvoke 来避免界面假死, 但是这样做时,某些代码或者是某个方法的执行超时的时间还是无法操控的.那么我们又是否有一种比较通用的方法.来设定某一个方法的执行超时的时间,让该其一旦超过指定时间则跳出指定方法.进而继续向下执行呢? 答案当然是肯定的. delegate.BeginInvoke可以实现代

python设定并获取默认的套接字超时时间

当需要处理socket库某些属性的默认值,例如套接字超时时间.你可以创建一个套接字对象实例,调用settimeout()法设定一个超时时间,在调用gettimeout()方法获取默认的超时时间,.这种操作在开发服务器应用时很有用. 技术点解析: 1.定义socket_timeout()函数,注意函数缩进格式. 2.socket库中的类函数创建一个套接字对象 使用socket.socket(socket.AF_INET,socket.SOCK_STREAM)首先创建了一个套接字对象socket()

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

在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API的一部分,在java.util.concurrent包中.Future接口是Java线程Future模式的实 现,可以来进行异步计算. Future模式可以这样来描述:我有一个任务,提交给了Future,Future替我完成这个任务.期间我自己可以去做任何想做的事情.一段时 间之后,我就便可以从Future那儿取出结果.就相当

CURL超时时间设置

一次完整的http请求,一般包含三个步骤: 通过DNS把域名解析成IP 通过IP地址连接到目标主机 获取目标主机数据(1.给目标主机输出http请求头,以\r\n\r\n结尾:2.获取目标主机传过来的数据) php 的 curl 对以上三个步骤都有设置超时时间的方法 1.保存DNS信息时间 CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,默认为120秒. 2.连接超时时间 CURLOPT_CONNECTTIMEOUT 以秒为单位.如果设置为0,则无限等待.

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

Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超时时间已过或服务器未响应"的情况 分析 造成这一问题的原因大概有以下几点:     1.Asp.net请求超时         2.Webservice请求超时          3.IIS请求超时          4.数据库连接超时 凭经验判断,应当是数据库连接超时造成,根据在网上找到的解决方法

java测试网络连接是否成功并设置超时时间

/** * 获取RMI接口状态 * * @return "0":服务正常,"1": 连接报错,"2":连接超时 */ @Override public String getRMIJkzt() { final ExecutorService es = Executors.newFixedThreadPool(1); Callable<String> callable = new Callable<String>() {//使

关于PHP执行超时的问题

PHP配置文件的参数max_execution_time表示脚本执行超时时间 max_execution_time=0表示不限制 max_execution_time=2表示执行两秒后终止,同时报错Fatal error: Maximum execution time of 2 seconds exceeded 但是,sleep(10)函数是不起作用的. 例如,php.ini中的max_execution_time=2 执行代码 <?php sleep(10);echo 'ok'; ?> 是不

RMI 连接超时时间设定

System.setProperty("sun.rmi.transport.tcp.responseTimeout", "2000"); System.setProperty("sun.rmi.transport.tcp.readTimeout", "2000"); System.setProperty("sun.rmi.transport.connectionTimeout", "2000&qu

设置调用方法的超时时间

在工作中,遇到这样一个需求,我要做一个业务,要验证一下现有的数据是否正确,但这个验证又不是必须的,只是说如果这里验证不通过,后面流程就可以不走了,但是如果这里没有验证到,后面也会有验证.也就是说不影响主流程,算得上是一个优化吧.比如我要查询一个东西,但是这个时间不能超过1秒. 在网上查了一下,基本上都是异步执行,有两个线程来做.我查到有两种方法. 第一种 独立成一个类 代码如下: (1).FuncTimeOut类 /// <summary> /// 超时设置类 /// </summary