user764754 user764754 - 28 days ago 7
C# Question

Are expression trees thread-safe?

I want to cache some expressions that are generated dynamically (with LinqKit) in order to pass them to a

Where
clause that is part of an Entity Framework query.

So I have something like

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
}


Is it safe for multiple threads to call
Apply
and then execute those queries in parallel? Is the
Expression<TDelegate>
class thread-safe?

Docs only give the standard "Any public static (Shared in Visual Basic) members of this type are thread safe..."

Answer

Expression trees themselves are immutable. However, they can refer to things that do change, e.g.

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 your expression tree only refers to things that don't change, it should be fine. That will be the case in most situations.

If your expression tree does refer to mutable state, the if one thread mutates that state, other threads applying the expression tree may or may not see the change, in the normal way of memory models.

Comments