2

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);
    }
}
Benjol
  • 63,995
  • 54
  • 186
  • 268

2 Answers2

1

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).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Yeees, that's an idea I had too. I may yet resort to that, but it's a bit fragile, copy-paste being what it is... – Benjol Nov 03 '08 at 12:34
  • Well, if you wanted to get *really* grungy you could use StackFrame to get this before using Control.Invoke - but this is very messy... – Marc Gravell Nov 03 '08 at 12:40
1

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.

Dave Cluderay
  • 7,268
  • 1
  • 29
  • 28