Benjol
Benjol

Reputation: 66541

How to get information about an exception raised by the target of Control.Invoke

I have a 'generic' boiler plate static method for checking for InvokeRequired and invoking an associated action accordingly.

If an unhandled exception is raised by the action, the stack trace isn't much help because it starts from here. I can get information about the control, but that isn't always much help. I was wondering if it is possible to get 'something' useful out of the Action - other that 'Target'. (Note that the Action is often a lambda or anonymous delegate...)

    public static void Invoke(Control ctrl, Action action)
    {
        if (ctrl == null)
            throw new ArgumentNullException("ctrl");
        if (action == null)
            return;

        var invokeRequired = ctrl.InvokeRequired;
        try
        {
            if (ctrl.InvokeRequired)
                ctrl.Invoke(action);
            else
                action();
        }
        catch (Exception ex)
        {
            throw new Exception(String.Format("Invoke error, ctrl={0}, action Target={1}", ctrl.Name, action.Target), ex);
        }
    }

EDIT: In line with this answer, here is the new overload (also slightly improved)

public static void Invoke(Control ctrl, Action action, string context)
{
    if (ctrl == null)
        throw new ArgumentNullException("ctrl");
    if (action == null)
        return; //not sure it's worththrowing an exception here...

    var invokeRequired = ctrl.InvokeRequired;
    try
    {
        if (invokeRequired)
            ctrl.Invoke(action);
        else
            action();
    }
    catch (Exception ex)
    {
        var ps = invokeRequired ? "" : " - has the target control been initialised?";
        var errmsg = String.Format("Invoke error, ctrl={0}, action Target={1}, context={2}{3}", ctrl.Name, action.Target, context, ps);
        throw new Exception(errmsg, ex);
    }
}

Upvotes: 2

Views: 1084

Answers (2)

Dave Cluderay
Dave Cluderay

Reputation: 7426

If I've read correctly, you are wanting to access the details of the original exception that occurred. You should be able to get that by checking the InnerException property on the ex variable.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062895

Well, .Method.Name will give you the method being invoked but in the case of anonymous methods / lambdas: no, not really. The compiler-generated names are fairly unintelligible, and you can't easily parse a delegate's IL. Your best bet might be to include an optional string argument (for blame purposes; if omitted, use the .Method.Name).

Upvotes: 1

Related Questions