主要使用BeginInvoke方法和ManualResetEvent类来实现。
BeginInvoke使得函数在线程池上异步运行,运行完成后,调用回调函数。
ManualResetEvent用于同步阻塞。
设计思想如下:
当函数在线程池中的某一线程上异步的运行的时候,ManualResetEvent阻塞当前线程,等待若干时间。
在等候期间,如果异步函数运行完毕,会对ManualResetEvent设置一个信号,使得阻塞的线程得以继续运行下去。
如果等候超时了,则阻塞的线程也会取消阻塞,继续运行下去,但是不再理会回调的函数。(即使回调函数仍然被调用),事实上,BeginInvoke创建的线程都是后台线程,这种线程一但所有的前台线程都退出后(其中主线程就是一个前台线程),不管后台线程是否执行完毕,都会结束线程,并退出。因此如果阻塞的主线程完全运行完毕退出,那么异步运行的线程也会退出,无论是否运行完毕。
语句isGetSignal = manu.WaitOne(timeout);就是阻塞当前线程一段时间。
该语句阻塞期间,不会对isGetSignal赋值,直到阻塞取消后,才会返回一个值给isGetSignal。
当阻塞是因为收到信号而取消的,得到的值是true。
当阻塞是因为超时而取消的,得到的值是false。
整个流程如下:

把这些代码逻辑封装成一个类。
这个类就接受一个委托和一个超时时间作为构造函数。
把这个委托和 ManualResetEvent .Set();语句写在一个方法体内,CombineActionAndManuset,因此CombineActionAndManuset的调用就是实现了方法运行完毕后,设置取消阻塞信号。
封装后的代码:
- public class FuncTimeout
- {
-
-
-
- public ManualResetEvent manu = new ManualResetEvent(false);
-
-
-
-
- public bool isGetSignal;
-
-
-
- public int timeout;
-
-
-
- public Action<int> FunctionNeedRun;
-
-
-
-
-
-
- public FuncTimeout(Action<int> _action, int _timeout)
- {
- FunctionNeedRun = _action;
- timeout = _timeout;
- }
-
-
-
-
-
- public void MyAsyncCallback(IAsyncResult ar)
- {
-
- if (isGetSignal == false)
- {
- Console.WriteLine("放弃执行回调函数");
- Thread.CurrentThread.Abort();
- }
- else
- {
- Console.WriteLine("调用回调函数");
- }
- }
-
-
-
-
-
- public void doAction(int param1)
- {
- Action<int> WhatTodo = CombineActionAndManuset;
-
- var r=WhatTodo.BeginInvoke(param1, MyAsyncCallback, null);
-
-
- isGetSignal = manu.WaitOne(timeout);
-
- if (isGetSignal == true)
- {
- Console.WriteLine("函数运行完毕,收到设置信号,异步执行未超时");
- }
- else
- {
- Console.WriteLine("没有收到设置信号,异步执行超时");
- }
- }
-
-
-
-
-
-
- public void CombineActionAndManuset(int num)
- {
- FunctionNeedRun(num);
- manu.Set();
- }
- }
测试代码:
- class Program
- {
- static void Main(string[] args)
- {
- FuncTimeout ft = new FuncTimeout(dosth, 3000);
- ft.doAction(6);
- }
-
- static void dosth(int num)
- {
- for (int i = 0; i < num; i++)
- {
- Thread.Sleep(500);
- Console.Write(i);
- }
- }
- }
当超时时间设置为5s的时候,方法未超时

当超时时间设置为1s的时候,方法超时

附件:http://down.51cto.com/data/2361797