Je connais. Une question similaire a déjà été posée.
mais je n’ai pas la solution exacte de cela.
J’ai un événement de clic de bouton dans lequel j’ai une méthode FillCombo()
.
Bouton clic événement
private void button1_Click(object sender, EventArgs e) { try { cmbTemplates.Items.Clear(); lstFiles.Clear(); FillCombo(); } catch (Exception ex) { MethodBase site = ex.TargetSite; Log(ex.ToSsortingng(), site == null ? null : site.Name); } }
Lors du débogage, j’ai constaté que l’exception se produisait à partir de la méthode FillCombo()
. Après cela, j’obtiens la valeur de site.Name
comme WinIOError
au lieu de FillCombo
.
J’ai essayé une autre méthode GetExecutingMethodName()
laquelle Chris Gessler a répondu dans Comment obtenir le nom de la méthode à l’origine de la question de l’exception . J’ai donc essayé d’envoyer le nom de la méthode qui a provoqué une exception à l’aide de la méthode GetExecutingMethodName()
Log(ex.ToSsortingng(), GetExecutingMethodName());
Mais j’ai obtenu le résultat comme System.Windows.Forms.Control.OnClick
au lieu de FillCombo
.
Comment puis-je obtenir le nom réel de la méthode qui a provoqué une exception?
.net prend en charge l’obtention des informations de trace de stack à partir d’une exception. Vous pouvez filtrer la méthode (et son nom) en examinant la première image (origine).
new StackTrace(ex).GetFrame(0).GetMethod().Name
Cela vous donnerait probablement exactement le même que le site cible (le win io), mais vous pouvez examiner le stacktrace pour le premier code utilisateur, ou la première image de votre type, ou selon vos besoins.
Par exemple, obtenir le nom du lanceur coupable dans votre assemblage actuel:
var s = new StackTrace(ex); var thisasm = Assembly.GetExecutingAssembly(); var methodname = s.GetFrames().Select(f => f.GetMethod()).First(m => m.Module.Assembly == thisasm).Name;
Il est important de comprendre ce que l’on entend par “la méthode qui a jeté l’exception”. Lorsqu’une exception se produit, une méthode spécifique est en cours d’exécution. Le fait que vous ayez appelé votre propre méthode FillCombo()
à un moment donné avant l’exception ne signifie pas que c’est la méthode qui a levé l’exception.
La méthode FillCombo()
sera toutefois (dans le cas où cela vous importe ici) dans la trace de la stack. C’est pourquoi il est utile de consigner toute la trace de la stack. En effet, je viens généralement de connecter l’ensemble de l’object Exception
(c’est-à-dire ex.ToSsortingng()
, ou simplement de transmettre l’object exception à ssortingng.Format()
ou similaire qui appelle ToSsortingng()
pour vous). Cela inclura le type d’exception, le message, la trace entière de la stack et même les informations sur les exceptions internes, le cas échéant.
Le code que vous avez obtenu de l’autre question, pour la méthode GetExecutingMethodName()
, n’est pas vraiment utile à GetExecutingMethodName()
. Vous remarquerez qu’il s’agit en réalité d’parsingr la trace de stack de l’emplacement d’exécution en cours , en recherchant la première méthode déclarée dans un type autre que celui où GetExecutingMethodName()
été déclaré.
Ceci est faux pour votre but pour deux raisons:
Control.OnClick()
(c’est-à-dire la méthode qui déclenche réellement l’événement). Franchement, je trouve cette réponse particulière étrange, car .NET fournit déjà une API permettant de récupérer le MethodInfo
de la méthode en cours d’exécution: MethodBase.GetCurrentMethod . Et ceci est bien plus fiable que le code écrit par Chris Gessler.
button1_Click()
. Mais vous le savez déjà, car le code que vous écrivez pour gérer l’exception se trouve dans cette méthode. Si vous voulez connaître le nom de la méthode dans votre méthode en cours d’exécution qui a été appelée avant que l’exception ne se produise, vous pouvez combiner les deux techniques: obtenir le nom de la méthode en cours d’exécution, puis le transmettre à une méthode prenant à la fois et la chaîne de trace de stack de l’object Exception
et laissez cette méthode parsingr la chaîne de trace de stack pour rechercher le cadre juste avant la méthode en cours d’exécution dans la trace.
C’est un peu pénible, mais cela pourrait être fait. Voici un exemple de ce à quoi cela pourrait ressembler (programme de console de validation de concept simple):
static void Main(ssortingng[] args) { try { CallForException(); } catch (Exception e) { Console.WriteLine("Exception occurred calling {0} method", GetCallForExceptionThisMethod(MethodBase.GetCurrentMethod(), e)); } } private static ssortingng GetCallForExceptionThisMethod(MethodBase methodBase, Exception e) { StackTrace trace = new StackTrace(e); StackFrame previousFrame = null; foreach (StackFrame frame in trace.GetFrames()) { if (frame.GetMethod() == methodBase) { break; } previousFrame = frame; } return previousFrame != null ? previousFrame.GetMethod().Name : null; } private static void CallForException() { DoActualException(); } private static void DoActualException() { throw new NotImplementedException(); }
Enfin, gardez à l’esprit qu’en raison de l’intégration de la méthode et d’autres optimisations, même une trace de stack complète peut comporter des irrégularités, notamment le fait de ne pas avoir le nom réel de la méthode où l’exception a été générée. C’est une autre raison pour laquelle la journalisation de l’intégralité de l’object Exception
est généralement beaucoup plus utile. plus il y a de contexte, plus vous avez de chances de pouvoir reconstruire ce qui s’est passé.
Essayez ceci:
var methodFullName = exception.TargetSite.ReflectedType.FullName