Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are expression trees thread-safe?

Tags:

c#

.net

lambda

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..."

like image 288
user764754 Avatar asked Nov 05 '16 19:11

user764754


People also ask

What is an expression tree and how is it useful?

When you want to have a richer interaction, you need to use Expression Trees. Expression Trees represent code as a structure that you can examine, modify, or execute. These tools give you the power to manipulate code during run time. You can write code that examines running algorithms, or injects new capabilities.

What is expression trees and how they used in LINQ?

You can compile and run code represented by expression trees. This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries. For more information about expression trees in LINQ, see How to use expression trees to build dynamic queries (C#).

Why do we need expression tree?

Expression trees are often used to generate code dynamically at runtime. Lets say that you have to create lots of unknown type insatnces. You could create them using reflection and you'll suffer from poor performance, or you can create an expression tree and compile it to a method.

How do you run expression tree?

Expression trees that represent lambda expressions are of type LambdaExpression or Expression<TDelegate>. To execute these expression trees, call the Compile method to create an executable delegate, and then invoke the delegate.


1 Answers

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.

like image 153
Jon Skeet Avatar answered Sep 21 '22 21:09

Jon Skeet