Exemple #1
0
        private void WaitFor(Delegate func, object[] parameters, int timeout, int maxNoOfRetry, int sleepBetweenRetry, ChoExecutionServiceData data)
        {
            ChoGuard.ArgumentNotNull(func, "Function");

            ChoAbortableAsyncResult asyncResult = data.Result as ChoAbortableAsyncResult;

            if (_timeout > 0)
            {
                timeout = timeout > _timeout ? _timeout : timeout;
            }
            if (_maxNoOfRetry > 0)
            {
                maxNoOfRetry = maxNoOfRetry > _maxNoOfRetry ? _maxNoOfRetry : maxNoOfRetry;
            }
            if (_sleepBetweenRetry > 0)
            {
                sleepBetweenRetry = sleepBetweenRetry > _sleepBetweenRetry ? _sleepBetweenRetry : sleepBetweenRetry;
            }

            if (maxNoOfRetry > 0 && sleepBetweenRetry <= 0)
            {
                sleepBetweenRetry = 1000;
            }

            //ChoWaitFor.CheckParams(timeout, maxNoOfRetry, sleepBetweenRetry);

            int                 noOfRetry     = 0;
            object              retValue      = null;
            AutoResetEvent      _event        = new AutoResetEvent(false);
            ChoList <Exception> aggExceptions = new ChoList <Exception>();
            Func <object>       wrappedFunc   = delegate
            {
                if (asyncResult.AbortRequested)
                {
                    //asyncResult.SetAsAborted(true);
                    return(null);
                }

                asyncResult.ThreadToKill = Thread.CurrentThread;
                _event.Set();
                return(func.DynamicInvoke(parameters));
            };

            while (true)
            {
                if (asyncResult.AbortRequested)
                {
                    //asyncResult.SetAsAborted(true);
                    break;
                }

                try
                {
                    if (timeout == System.Threading.Timeout.Infinite)
                    {
                        retValue = wrappedFunc.Invoke();
                    }
                    else
                    {
                        _event.Reset();
                        IAsyncResult result = wrappedFunc.BeginInvoke(null, null);
                        _event.WaitOne();
                        //Thread.Sleep(1000);
                        //using (result.AsyncWaitHandle)
                        //{
                        if (!result.AsyncWaitHandle.WaitOne(timeout, true))
                        {
                            if (asyncResult.ThreadToKill != null && asyncResult.ThreadToKill.IsAlive)
                            {
                                try
                                {
                                    asyncResult.ThreadToKill.Abort();
                                }
                                catch (ThreadAbortException)
                                {
                                    Thread.ResetAbort();
                                }
                            }
                            throw new ChoTimeoutException(String.Format("The method failed to execute within {0} sec.", timeout));

                            //ChoWaitFor.RaiseTimeoutException(func, timeout);
                        }
                        else
                        {
                            try
                            {
                                retValue = wrappedFunc.EndInvoke(result);
                            }
                            catch (ThreadAbortException)
                            {
                                //Thread.ResetAbort();
                                asyncResult.SetAsAborted(true);
                                return;
                            }
                        }
                        //}
                    }
                    asyncResult.SetAsSuccess(retValue, true);
                    return;
                }
                catch (ThreadAbortException)
                {
                    Thread.ResetAbort();
                    //ChoTrace.Debug("Thread Aborted.");
                    //ChoTrace.Debug(data.ToString());
                    asyncResult.SetAsAborted(true);
                    break;
                }
                catch (ChoFatalApplicationException fEx)
                {
                    asyncResult.SetAsFailed(fEx, true);
                    throw;
                }
                catch (Exception ex)
                {
                    if (maxNoOfRetry != 0)
                    {
                        if (noOfRetry == maxNoOfRetry)
                        {
                            asyncResult.SetAsFailed(new ChoAggregateException(String.Format("The method failed to execute after {0} retries.", maxNoOfRetry), aggExceptions), true);
                            return;
                        }

                        noOfRetry++;
                        if (ex is TargetInvocationException)
                        {
                            aggExceptions.Add(ex.InnerException);
                            asyncResult.SetAsFailedWithRetry(ex.InnerException, noOfRetry);
                        }
                        else
                        {
                            aggExceptions.Add(ex);
                            asyncResult.SetAsFailedWithRetry(ex, noOfRetry);
                        }

                        Thread.Sleep((int)sleepBetweenRetry);
                    }
                    else
                    {
                        //ChoProfile.WriteLine(ex.ToString());
                        //ChoProfile.WriteLine(data.ToString());
                        if (ex is TargetInvocationException)
                        {
                            asyncResult.SetAsFailed(ex.InnerException != null ? ex.InnerException : ex, true);
                        }
                        else
                        {
                            asyncResult.SetAsFailed(ex, true);
                        }

                        return;
                    }
                }
            }
        }