表达式树是线程安全的吗?
Are expression trees thread-safe?
我想缓存一些动态生成的表达式(使用 LinqKit),以便将它们传递给作为 Entity Framework 查询一部分的 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>
class 线程安全吗?
文档只给出标准"Any public static (Shared in Visual Basic) members of this type are thread safe..."
表达式树本身是不可变的。但是,它们可以指代做改变的事情,例如
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);
}
}
}
如果你的表达式树只引用不会改变的东西,那应该没问题。在大多数情况下都是如此。
如果您的表达式树 确实 引用可变状态,如果一个线程改变了该状态,则应用表达式树的其他线程可能会也可能不会看到更改,在正常情况下内存模型的方式。
我想缓存一些动态生成的表达式(使用 LinqKit),以便将它们传递给作为 Entity Framework 查询一部分的 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>
class 线程安全吗?
文档只给出标准"Any public static (Shared in Visual Basic) members of this type are thread safe..."
表达式树本身是不可变的。但是,它们可以指代做改变的事情,例如
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);
}
}
}
如果你的表达式树只引用不会改变的东西,那应该没问题。在大多数情况下都是如此。
如果您的表达式树 确实 引用可变状态,如果一个线程改变了该状态,则应用表达式树的其他线程可能会也可能不会看到更改,在正常情况下内存模型的方式。