En fait, il existe certaines situations dans lesquelles la throwdéclaration ne conservera pas les informations StackTrace. Par exemple, dans le code ci-dessous:
try
{
  int i = 0;
  int j = 12 / i; // Line 47
  int k = j + 1;
}
catch
{
  // do something
  // ...
  throw; // Line 54
}
Le StackTrace indiquera que la ligne 54 a soulevé l'exception, bien qu'elle ait été soulevée à la ligne 47.
Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.
   at Program.WithThrowIncomplete() in Program.cs:line 54
   at Program.Main(String[] args) in Program.cs:line 106
Dans des situations comme celle décrite ci-dessus, il existe deux options pour préconfigurer le StackTrace d'origine:
Appel de l'exception.InternalPreserveStackTrace
Comme il s'agit d'une méthode privée, elle doit être invoquée en utilisant la réflexion: 
private static void PreserveStackTrace(Exception exception)
{
  MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
    BindingFlags.Instance | BindingFlags.NonPublic);
  preserveStackTrace.Invoke(exception, null);
}
J'ai un inconvénient à compter sur une méthode privée pour conserver les informations StackTrace. Il pourra être modifié dans les futures versions de .NET Framework. L'exemple de code ci-dessus et la solution proposée ci-dessous ont été extraits du blog Fabrice MARGUERIE .
Appel d'Exception.SetObjectData
La technique ci-dessous a été suggérée par Anton Tykhyy comme réponse à In C #, comment puis-je relancer InnerException sans perdre la question de trace de pile .
static void PreserveStackTrace (Exception e) 
{ 
  var ctx = new StreamingContext  (StreamingContextStates.CrossAppDomain) ; 
  var mgr = new ObjectManager     (null, ctx) ; 
  var si  = new SerializationInfo (e.GetType (), new FormatterConverter ()) ; 
  e.GetObjectData    (si, ctx)  ; 
  mgr.RegisterObject (e, 1, si) ; // prepare for SetObjectData 
  mgr.DoFixups       ()         ; // ObjectManager calls SetObjectData 
  // voila, e is unmodified save for _remoteStackTraceString 
} 
Bien qu'il ait l'avantage de s'appuyer uniquement sur des méthodes publiques, il dépend également du constructeur d'exceptions suivant (que certaines exceptions développées par des tiers ne mettent pas en œuvre):
protected Exception(
    SerializationInfo info,
    StreamingContext context
)
Dans ma situation, j'ai dû choisir la première approche, car les exceptions soulevées par une bibliothèque tierce que j'utilisais n'ont pas implémenté ce constructeur.