Wie kann ich eine break-Anweisung in einer kompilierten Ausdrucksstruktur debuggen oder setzen?

c# debugging expression-trees linq

Frage

Wenn eine externe Bibliothek einen LINQ-Provider enthält und beim Ausführen eines dynamischen Ausdrucksbaums eine Ausnahme auslöst, wie kann ich beim Auslösen dieses Ausdrucks einen Abbruch vornehmen?

Zum Beispiel verwende ich einen LINQ2CRM-Provider von Drittanbietern, der es mir erlaubt, die Max<TSource, TResult>() -Methode von IQueryable , aber wenn eine InvalidCastException , kann ich nicht an der Stelle brechen, wenn die Ausnahme ausgelöst wird Es ist schwer, den Stack-Trace zu überprüfen, da er bereits unbändig ist, wenn der Debugger ihn in meinem Code unterbricht. Ich habe für die erwähnte Ausnahme "Break On Throw" gesetzt. Meine Debug-Einstellungen sind:

Bildbeschreibung hier eingeben


Klärung, wo genau ich brechen möchte. Ich möchte nicht in den LINQ-Ausdruck einbrechen, sondern stattdessen, wenn der Ausdrucksbaum ausgeführt wird, oder, mit anderen Worten, wenn die IQueryable Erweiterungsmethode Max() die vom LINQ-Provider bereitgestellte Überschreibung aufruft. Der obere Teil des Stacktrace sieht so aus, und an dieser Stelle möchte ich in das Innere einbrechen (oder durchgehen oder was auch immer):

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

Akzeptierte Antwort

Ich verstehe das Problem vielleicht nicht, aber anstatt es tatsächlich zu unterbrechen (was nicht möglich scheint), würde es ausreichen, einen try-catch in Ihren Ausdrucksbaum zu setzen und die Ausnahme zu protokollieren?

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

Konsolenausgabe:

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 )


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum