public void InvokeCallback(object sender, object args)
            {
                if (IsBusy)
                {
                    return;
                }

                if (IsBlocking)
                {
                    IsBusy = true;
                }

                if (Source != null && sender != Source)
                {
                    IsBusy = false;
                    return;
                }

                var target = DelegateSource.Target;

                if (target == null)
                {
                    IsBusy = false;
                    return; // Collected
                }

                var parameters = MethodInfo.GetParameters().Length == 1
                    ? new[] { sender }
                    : new[] { sender, args };

                if (MethodInfo.ReturnType != typeof(Task))
                {
                    try
                    {
                        MethodInfo.Invoke(MethodInfo.IsStatic ? null : target, parameters);
                    }
                    catch (Exception ex)
                    {
                        SafeExecutionHelpers.HandleException(ex, OnException);
                    }
                    finally
                    {
                        IsBusy = false;
                    }
                }
                else
                {
                    Task.Run(() => ((Task)MethodInfo
                                    .Invoke(MethodInfo.IsStatic
                                    ? null
                                    : target
                                            , parameters))
                             .HandleException(OnException)
                             .ContinueWith(t => IsBusy = false));
                }
            }
        /// <summary>
        /// For unit testing and mocking of <see cref="SafeTaskExtensions"/>
        /// </summary>
        public Task InternalHandleExceptionLogic <TException>(Task task, Action <TException> onException, TaskScheduler scheduler = null) where TException : Exception
        {
            task.ContinueWith(
                t => SafeExecutionHelpers
                .HandleException <TException>(t.Exception.InnerException, onException)
                , CancellationToken.None
                , TaskContinuationOptions.OnlyOnFaulted
                , scheduler ?? TaskScheduler.Default);

            return(task);
        }
 /// <summary>
 /// For unit testing and mocking of <see cref="SafeActionExtensions"/>
 /// </summary>
 public void InternalSafeInvoke <TException>(Action action, Action <TException> onException)
     where TException : Exception
 {
     try
     {
         action();
     }
     catch (TException ex) when(SafeExecutionHelpers.Settings.DefaultExceptionHandler != null || onException != null)
     {
         SafeExecutionHelpers.HandleException(ex, onException);
     }
 }
 /// <summary>
 /// For unit testing and mocking of <see cref="SafeActionExtensions"/>
 /// </summary>
 public void InternalSafeInvoke <TException>(
     Action <object> action,
     object parameter,
     Action <TException> onException)
     where TException : Exception
 {
     try
     {
         action(parameter);
     }
     catch (TException ex)
     {
         SafeExecutionHelpers.HandleException(ex, onException);
     }
 }