// 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();
            }
        }
示例#2
0
        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();
                //}
            }
        }