表达树是线程安全的吗?

时间:2016-11-05 19:14:06

标签: c# .net lambda

我想缓存一些动态生成的表达式(使用LinqKit),以便将它们传递给属于实体框架查询的Where子句。

所以我有类似

的东西
private static Expression<Func<T, bool>> _expression; // Gets a value at runtime

public IQueryable<T> Apply(IQueryable<T> query) 
{        
    return query.Where(_expression); // Here _expression already has a value
}

多个线程调用Apply然后并行执行这些查询是否安全? Expression<TDelegate>类是否是线程安全的?

文档仅提供标准&#34;此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的...&#34;

1 个答案:

答案 0 :(得分:13)

表达式树本身是不可变的。但是,他们可以引用更改的内容,例如

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

public class Test
{
    static void Main()
    {
        int multiplier = 3;
        IQueryable<int> values = new List<int> { 1, 2 }.AsQueryable();
        Expression<Func<int, int>> expression = x => x * multiplier;

        // Prints 3, 6
        foreach (var item in values.Select(expression))
        {
            Console.WriteLine(item);
        }

        multiplier = 5;

        // Prints 5, 10
        foreach (var item in values.Select(expression))
        {
            Console.WriteLine(item);
        }
    }
}

如果你的表达树只引用了不会改变的东西,它应该没问题。大多数情况都是如此。

如果表达式树 引用可变状态,则if一个线程会改变该状态,应用表达式树的其他线程可能会或可能不会以正常的内存模型方式看到更改。