Comment puis-je déboguer ou définir une instruction break dans un arbre d'expression compilé?

c# debugging expression-trees linq

Question

Lorsqu'une bibliothèque externe contient un fournisseur LINQ et qu'elle lève une exception lors de l'exécution d'une arborescence d'expressions dynamiques, comment puis-je interrompre l'exécution de cette expression?

Par exemple, j’utilise un fournisseur LINQ2CRM tiers, qui me permet d’appeler la méthode IQueryable Max<TSource, TResult>() , mais lorsqu’il lève une InvalidCastException , je ne parviens pas à casser sur place lorsque l’exception est levée. Il est difficile de passer en revue la trace de pile car elle est déjà déroulée lorsque le débogueur l'envoie dans mon code. J'ai mis "break on throw" pour l'exception mentionnée. Mes paramètres de débogage sont les suivants:

entrez la description de l'image ici


Clarification sur l'endroit où j'aimerais faire une pause. Je ne souhaite pas interrompre l'expression LINQ, mais plutôt lorsque l'arborescence d'expression est exécutée ou, en d'autres termes, lorsque la méthode d'extension IQueryable Max() appelle le remplacement fourni par le fournisseur LINQ. Voici le haut de la pile, où je voudrais faire une brèche à l'intérieur (ou passer, ou peu importe):

at XrmLinq.QueryProviderBase.Execute[T](Expression expression)
at System.Linq.Queryable.Max[TSource,TResult](IQueryable`1 source, Expression`1 selector)

Réponse acceptée

Je ne comprends peut-être pas le problème, mais au lieu de casser la ligne (ce qui ne semble pas possible), serait-il suffisant d'insérer un try-catch dans votre arbre d'expression et de consigner l'exception?

static void Main(string[] args)
{
    var logExceptionMethod = typeof (Program).GetMethod("LogException", BindingFlags.Static | BindingFlags.NonPublic);
    var createFileMethod = typeof (System.IO.File).GetMethod("Create", new[] {typeof(string)});

    // Parameter for the catch block
    var exception = Expression.Parameter(typeof(Exception));

    var expression =
        Expression.TryCatch(
        Expression.Block(typeof(void),
            // Try to create an invalid file
            Expression.Call(createFileMethod, Expression.Constant("abcd/\\"))),

            // Log the exception from the catch                  
            Expression.Catch(exception, Expression.Call(logExceptionMethod, exception)));

    Expression.Lambda<Action>(expression).Compile()();
}

static void LogException(Exception ex)
{
    Console.WriteLine(ex.Message + "\r\n" + ex.StackTrace);
}

Sortie de la console:

The filename, directory name, or volume label syntax is incorrect.

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.File.Create(String path)
at lambda_method(Closure )


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow