2008-11-03 5 views
2

У меня есть статический метод «универсальной» котельной пластины для проверки InvokeRequired и вызова соответствующего действия соответственно.Как получить информацию об исключении, поднятом целевым объектом Control.Invoke

Если необработанное исключение возбуждается действием, трассировка стека не очень помогает, поскольку она начинается здесь. Я могу получить информацию об управлении, но это не всегда помогает. Мне было интересно, можно ли извлечь «что-то» из действия - другое, что «Цель». (Обратите внимание, что действие часто является лямбда или анонимный делегат ...)

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: В соответствии с этим ответом, вот новая перегрузка (также немного улучшенный)

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); 
    } 
} 

ответ

1

Ну, .Method.Name даст вам метод, который вызывается, но в случае анонимных методов/lambdas: нет, на самом деле. Созданные компилятором имена довольно непонятны, и вы не можете легко проанализировать IL-делегат. Лучше всего включить необязательный строковый аргумент (для целей вины, если он опущен, используйте .Method.Name).

+0

Yeees, это идея, которую я тоже имел. Я все же могу прибегнуть к этому, но он немного хрупкий, copy-paste - это то, что он ... – Benjol 2008-11-03 12:34:19

+0

Ну, если вы хотите получить * действительно * grungy, вы можете использовать StackFrame, чтобы получить это, прежде чем использовать Control.Invoke - но это очень грязно ... – 2008-11-03 12:40:18

1

Если я правильно прочитал, вы хотите получить доступ к деталям исходного произошедшего исключения. Вы должны получить это, проверив свойство InnerException для переменной ex.

Смежные вопросы