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); } }
Well,
.Method.Namewill 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).