做项目的时候有时经常会需要一个带有timeout功能的函数调用。
比如从后台读数据并期望在给定时间内返回。借此机会包装了一个简单的C# class, 直接上代码吧.
public class TimeoutInvokerWrapper { private ManualResetEvent mTimeoutObject; private bool mBoTimeout; private Func<object, object> doHandler; public string Error { get; private set; } public object Result { get; private set; } public TimeoutInvokerWrapper(Func<object, object> handler) { this.doHandler = handler; this.mTimeoutObject = new ManualResetEvent(true); } public bool DoWithTimeout(object input, TimeSpan timeSpan) { if (this.doHandler == null) { return false; } this.mTimeoutObject.Reset(); this.mBoTimeout = true; this.doHandler.BeginInvoke(input, DoAsyncCallBack, null); if (!this.mTimeoutObject.WaitOne(timeSpan, false)) { this.mBoTimeout = true; } return this.mBoTimeout; } private void DoAsyncCallBack(IAsyncResult result) { try { this.Result = this.doHandler.EndInvoke(result); this.mBoTimeout = false; } catch (Exception ex) { this.mBoTimeout = true; this.Error = ex.ToString(); } finally { this.mTimeoutObject.Set(); } } }
该类可以这样使用
public static void Main(string[] args) { Func<object, object> func = (obj) => { return obj.ToString(); }; TimeoutInvokerWrapper wrapper = new TimeoutInvokerWrapper(func); bool isTimeout = wrapper.DoWithTimeout(123, TimeSpan.FromSeconds(2)); if (isTimeout) { System.Console.WriteLine("function call timeout."); } else if (!string.IsNullOrEmpty(wrapper.Error)) { System.Console.WriteLine("function call does not timeout but throw exception."); } else { System.Console.WriteLine("call succeed.") System.Console.WriteLine(wrapper.Result); } }