编译Expression <t>时,是否隐式缓存?</t>

时间:2008-11-03 14:50:05

标签: c# .net linq caching expression

编译Expression<T>时,框架是否隐式缓存了生成的代码?我正在考虑静态Regex方法,其中框架隐式编译并缓存最后几个正则表达式。

如果编译的Expression<T>对象缓存,您是否可以推荐一些最佳实践来保持编译时间,或者如果我手动缓存表达式,可能会导致问题的任何问题?< / p>

public MyResultType DoSomething(int arg1, int arg2)
{
    var result = invokeHandler(
        (IDoSomethingHandler h) => h.DoSomething(arg1, arg2)
    );
    return result;
}

private TResult invokeHandler<T, TResult>(Expression<Func<T, TResult>> 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<T>();
    var result = compiledAction(handler);

    return result;
}

在这个例子中,我有点担心如果我缓存已编译的表达式,它将使用arg1arg2的值,因为它们是在编译表达式时的,而不是而不是从堆栈中的适当位置检索这些值(即,而不是获取当前值)。

2 个答案:

答案 0 :(得分:10)

没有;我不相信它;如果您希望缓存,则必须保留Delegate引用(通常为Func<...>Action<...>)。同样,如果你想获得最佳性能,你可以将它编译为参数化表达式,这样你就可以在调用它时发送不同的值。

在这种情况下,重新措辞会有所帮助:

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<T, TResult>(Expression<Func<T,int,int,TResult>> 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<T>();
    var result = compiledAction(handler, arg1, arg2);

    return result;
}

即。制作表达式的数字参数,并在运行时传递实际,而不是表达式中的常量。

答案 1 :(得分:2)

Lambda experssions不会自动缓存。您需要为此实现自己的缓存/记忆算法。检查相关的Stackoverflow问题:

Is it possible to cache a value evaluated in a lambda expression?

重要的是要注意lambda表达式在C#中是惰性求值。