/// <summary>
 /// Invokes a delegate asyncronously on any external object with the given params.
 /// This method automatically determines whether dynamic invoking is possible or a invoke over the ISynchronizeInvoke interface is required.
 /// The delegate has to be in the form Delegate(object sender, object param) for the invocation to work correctly.
 /// </summary>
 /// <param name="d">The delgate to invoke</param>
 /// <param name="param">The params for the invocation</param>
 /// <param name="sender">The sender param of the invocation</param>
 public static void InvokeExternalAsync(Delegate d, object param, object sender)
 {
     if (d != null)
     {
         foreach (Delegate dDelgate in d.GetInvocationList())
         {
             object objTarget = dDelgate.Target;
             if (objTarget != null && objTarget is System.ComponentModel.ISynchronizeInvoke &&
                 ((System.ComponentModel.ISynchronizeInvoke)(objTarget)).InvokeRequired)
             {
                 ((System.ComponentModel.ISynchronizeInvoke)(objTarget)).BeginInvoke(dDelgate, new object[] { sender, param });
             }
             else
             {
                 if (objTarget != null)
                 {
                     MethodInfo           miMethodInfo     = dDelgate.Method;
                     CachedMethodDelegate dChachedDelegate = GetOrAdd(miMethodInfo);
                     dChachedDelegate(objTarget, sender, param);
                 }
                 else
                 {
                     dDelgate.DynamicInvoke(sender, param);
                 }
             }
         }
     }
 }
        public static void InvokeExternal(Delegate d, object sender, EventArgs param)
        {
            if (d != null)
            {
                Delegate[] invocationList = d.GetInvocationList();
                foreach (Delegate subDelegate in invocationList)
                {
                    object target = subDelegate.Target;
                    if (
                        target != null &&
                        target is ISynchronizeInvoke &&
                        ((ISynchronizeInvoke)target).InvokeRequired
                        )
                    {
                        ((ISynchronizeInvoke)target).Invoke(subDelegate, new[] { sender, param });
                    }
                    else
                    {
    #if USE_FAST_INVOKE
                        MethodInfo methodInfo = subDelegate.Method;

                        CachedMethodDelegate del = GetOrAdd(s_cachedMethods, methodInfo, s_createDelegate);

                        del(target, sender, param);
    #else
                        dDelgate.DynamicInvoke(sender, param);
    #endif
                    }
                }
            }
        }