private T Execute <T>(Func <T> func, int timeout) { if (_thread == null) { throw new InvalidOperationException("Object has been disposed"); } AutoResetEvent ev = new AutoResetEvent(false); var item = new QueuedExecution { Func = () => func(), Trigger = ev }; _queue.Enqueue(item); AwaitTimeout(ev, timeout, item); object result; if (_results.TryRemove(ev, out result)) { Exception ex = result as Exception; if (ex != null) { Logger.Warn(ex.Message); Logger.Warn(ex.StackTrace); ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); } } return((T)result); }
public void Execute(Action func, int timeout = ThreadTimeout, bool expectLongOperation = false) { if (_thread == null) { throw new InvalidOperationException("Object has been disposed"); } AutoResetEvent ev = new AutoResetEvent(false); var item = new QueuedExecution { Action = () => func(), Trigger = ev, IsLongRunning = expectLongOperation }; _queue.Enqueue(item); AwaitTimeout(ev, timeout, item); if (_results.ContainsKey(ev)) { object val; if (_results.TryRemove(ev, out val)) { var ex = val as Exception; Logger.Warn(ex.Message); Logger.Warn(ex.StackTrace); ExceptionDispatchInfo.Capture(ex).Throw(); } } }
private void AwaitTimeout(AutoResetEvent ev, int timeout, QueuedExecution item) { if (ev.WaitOne(timeout, true)) { return; } // We're in a expected long running operation. Just wait. while (_exceptionOverride) { Logger.Info("Timed out during long running operation, awaiting.."); if (ev.WaitOne(timeout / 10, true)) { return; // Success } } throw new Exception($"Operation never terminated: Started: {item.IsStarted}"); }