Quando viene compilata un’espressione , è implicitamente memorizzata nella cache?

Quando viene compilata Expression , il codice risultante è implicitamente memorizzato nella cache dal framework? Sto pensando lungo le linee dei metodi statici Regex cui il framework compila implicitamente e memorizza nella cache le ultime regex.

Se gli oggetti Expression compilati non vengono memorizzati nella cache, puoi raccomandare alcune best practice per mantenere il tempo di compilazione inattivo o eventuali trucchi che potrebbero causare problemi se memorizzo manualmente in cache un’espressione?

 public MyResultType DoSomething(int arg1, int arg2) { var result = invokeHandler( (IDoSomethingHandler h) => h.DoSomething(arg1, arg2) ); return result; } private TResult invokeHandler(Expression<Func> action) where T : class { // Here, I might want to check to see if action is already cached. var compiledAction = action.Compile(); var methodCallExpr = action as MethodCallExpression; // Here, I might want to store methodCallExpr in a cache somewhere. var handler = ServiceLocator.Current.GetInstance(); var result = compiledAction(handler); return result; } 

In questo esempio, sono un po ‘preoccupato che se memorizzo l’espressione compilata nella cache, userà i valori di arg1 e arg2 come erano nel momento in cui è stata compilata l’espressione, piuttosto che recuperare quei valori dalla posizione appropriata nello stack (cioè piuttosto che ottenere i valori correnti).

No; Non credo che lo sia; se si desidera memorizzarlo nella cache, è necessario conservare il riferimento Delegate (in genere Func< ...> o Action< ...> ). Allo stesso modo, se si desidera ottenere la migliore prestazione, la si compila come espressione parametrizzata, quindi è ansible inviare valori diversi quando la si invoca.

In questo caso, la riformulazione potrebbe aiutare:

 public MyResultType DoSomething(int arg1, int arg2) { var result = invokeHandler( (IDoSomethingHandler h, int a1, int a2) => h.DoSomething(a1, a2), arg1, arg2); return result; } private TResult invokeHandler(Expression> action, int arg1, int arg2) where T : class { // Here, I might want to check to see if action is already cached. var compiledAction = action.Compile(); var methodCallExpr = action as MethodCallExpression; // Here, I might want to store methodCallExpr in a cache somewhere. var handler = ServiceLocator.Current.GetInstance(); var result = compiledAction(handler, arg1, arg2); return result; } 

vale a dire rendere i parametri numerici dell’espressione e passare quelli effettivi in fase di esecuzione (piuttosto che essere costanti nell’espressione).

Le expersioni Lambda non vengono memorizzate automaticamente nella cache. Sarà necessario implementare i propri algoritmi di memorizzazione nella cache / memoizzazione per quello. Controlla la relativa domanda StackOverflow:

È ansible memorizzare nella cache un valore valutato in un’espressione lambda?

È importante notare che le espressioni lambda sono pigre valutate in C #.