// From https://stackoverflow.com/questions/4359910/is-it-possible-to-abort-a-task-like-aborting-a-thread-thread-abort-method // jtrem's answer, but of course, with a "Don't Do This!!!" hahaha. protected async void CancellableCall(ProcessCall rc, int msTimeout) { var cts = new CancellationTokenSource(); var task = Task.Factory.StartNew(() => { try { using (cts.Token.Register(Thread.CurrentThread.Abort)) { rc.MakeCall(); } } catch (ThreadAbortException ex) { try { ProcessInstance(Logger, new ST_Exception(ex), true); } catch { } } catch (Exception ex) { try { ProcessInstance(Logger, new ST_Exception(ex), true); } catch { } } }, cts.Token); if (!(await Task.WhenAny(task, Task.Delay(msTimeout)) == task)) { cts.Cancel(); } }
protected void Call(ProcessCall rc) { try { rc.MakeCall(); } catch (Exception ex) { Exception ex2 = ex; // Prevent recursion if the exception process itself throws an exception. if (!(rc.SemanticInstance is ST_Exception)) { ProcessInstance(Logger, new ST_Exception(ex), true); } while (ex2.InnerException != null) { ex2 = ex2.InnerException; // Prevent recursion if the exception process itself throws an exception. if (!(rc.SemanticInstance is ST_Exception)) { ProcessInstance(Logger, new ST_Exception(ex2), true); } } } finally { if ((rc.Receptor is IDisposable) && (rc.AutoDispose)) { ((IDisposable)rc.Receptor).Dispose(); } } }
protected ProcStates Call(ProcessCall rc) { try { if (rc.Timeout == 0) { rc.MakeCall(); } else { // rc.MakeCall(); CancellableCall(rc, rc.Timeout); } // This is totally wrong: //if (msTimeout != 0) //{ // bool ok = Thread.CurrentThread.Join(msTimeout); // if (!ok) // { // return ProcStates.Timeout; // } //} return(ProcStates.OK); } catch (Exception ex) { Exception ex2 = ex; // Prevent recursion if the exception process itself throws an exception. if (!(rc.SemanticInstance is ST_Exception)) { try { ProcessInstance(Logger, new ST_Exception(ex), true); } catch { } } return(ProcStates.Exception); // The ST_Exception handler should deal with inner exceptions. /* * while (ex2.InnerException != null) * { * ex2 = ex2.InnerException; * // Prevent recursion if the exception process itself throws an exception. * if (!(rc.SemanticInstance is ST_Exception)) * { * try * { * ProcessInstance(Logger, new ST_Exception(ex2), true); * } * catch { } * } * } */ } finally { // TODO: // This looks wrong as well. If the call is on a thread, the receptor should be disposed once the call completes. // And oddly enough, we're setting autodispose to false on synchronous calls! The logic for this needs to be fixed, // so that dispose is called only on receptors that are created by the SP. //if ( (rc.Receptor is IDisposable) && (rc.AutoDispose) ) //{ // ((IDisposable)rc.Receptor).Dispose(); //} } }