Back to: LINQ Tutorial For Beginners and Professionals
Deferred Execution vs Immediate Execution in LINQ
In this article, I will discuss the difference between LINQ Deferred Execution vs Immediate Execution in C# with Examples. Please read our previous article discussing the LINQ Zip Method in C# with an Example. In LINQ (Language-Integrated Query), understanding the concepts of deferred execution and immediate execution is crucial, as they determine when the query is actually executed and the results are fetched. The LINQ queries are executed in two different ways, as follows.
- LINQ Deferred Execution
- LINQ Immediate Execution
Based on the above two types of Execution, the LINQ operators are divided into 2 categories. They are as follows:
- Deferred or Lazy Operators: These Query Operators are used for Deferred Execution. For example – Select, SelectMany, Where, Take, Skip, etc. belong to the Deferred or Lazy Operators Category.
- Immediate or Greedy Operators: These Query Operators are used for Immediate Execution. For example – Count, Average, Min, Max, First, Last, ToArray, ToList, etc., belong to the Immediate or Greedy Operators category.
LINQ Deferred Execution using C#:
Deferred execution means that the evaluation of an expression is delayed until its realized value is actually iterated over or demanded. In LINQ, most queries use deferred execution.
In this case, the LINQ Query is not executed at the point of its declaration. That means it doesn’t execute alone when we write a LINQ query. It executes only when we access the query results. So, here, the execution of the query is deferred until the query variable is iterated over using a for-each loop. Let us understand this with an example. The example below is self-explained. So, please go through the comment lines.
using System; using System.Collections.Generic; using System.Linq; namespace LINQDemo { public class Employee { public int ID { get; set; } public string Name { get; set; } public int Salary { get; set; } } class Program { public static void Main() { List<Employee> listEmployees = new List<Employee> { new Employee { ID= 1001, Name = "Priyanka", Salary = 80000 }, new Employee { ID= 1002, Name = "Anurag", Salary = 90000 }, new Employee { ID= 1003, Name = "Preety", Salary = 80000 } }; // In the below statement the LINQ Query is only defined and not executed // If the query is executed here, then the result should not display Santosh IEnumerable<Employee> result = from emp in listEmployees where emp.Salary == 80000 select emp; // Adding a new employee with Salary = 80000 to the collection listEmployees listEmployees.Add(new Employee { ID = 1004, Name = "Santosh", Salary = 80000 }); // The LINQ query is actually executed when we iterate thru using a for each loop // This is proved because Santosh is also included in the result foreach (Employee emp in result) { Console.WriteLine($" {emp.ID} {emp.Name} {emp.Salary}"); } Console.ReadKey(); } } }
Output:
Characteristics of Deferred Execution:
- The query definition itself does not trigger any data retrieval or computation.
- The query is executed when you iterate over the query variable (e.g., using for each) or apply an operator that forces immediate execution.
- This allows for query optimization and modification before execution.
Advantages of LINQ Deferred Execution in C#:
We will get the following advantages
- It avoids unnecessary query execution, which improves the performance of the application.
- The Query creation and the Query execution are decoupled, allowing us to create the query in several steps.
- A LINQ deferred execution query is always re-evaluated when we re-enumerate. As a result, we always get updated data.
- Efficiency: The query is executed only when needed.
- Flexibility: You can define a query once and execute it multiple times, potentially after modifying the source or the query.
LINQ Immediate Execution using C#
Immediate execution forces the query to run and the results to be fetched at the point of the query definition. In the case of Immediate Execution, the LINQ query is executed at the point of its declaration. So, it forces the query to execute and gets the result immediately. Let us see an example for a better understanding. The following example is self-explained. So, please go through the comment lines.
using System; using System.Collections.Generic; using System.Linq; namespace LINQDemo { public class Employee { public int ID { get; set; } public string Name { get; set; } public int Salary { get; set; } } class Program { public static void Main() { List<Employee> listEmployees = new List<Employee> { new Employee { ID= 1001, Name = "Priyanka", Salary = 80000 }, new Employee { ID= 1002, Name = "Anurag", Salary = 90000 }, new Employee { ID= 1003, Name = "Preety", Salary = 80000 } }; // In the following statement, the LINQ Query is executed immediately as we are // Using the ToList() method which is a greedy operator which forces the query // to be executed immediately IEnumerable<Employee> result = (from emp in listEmployees where emp.Salary == 80000 select emp).ToList(); // Adding a new employee with Salary = 80000 to the collection listEmployees // will not have any effect on the result as the query is already executed listEmployees.Add(new Employee { ID = 1004, Name = "Santosh", Salary = 80000 }); // The above LINQ query is executed at the time of its creation. // This is proved because Santosh is not included in the result foreach (Employee emp in result) { Console.WriteLine($" {emp.ID} {emp.Name} {emp.Salary}"); } Console.ReadKey(); } } }
Output:
Example:
In the following Immediate Execution example, we use the greedy operator, which returns a single value.
using System; using System.Collections.Generic; using System.Linq; namespace LINQDemo { public class Employee { public int ID { get; set; } public string Name { get; set; } public int Salary { get; set; } } class Program { public static void Main() { List<Employee> listEmployees = new List<Employee> { new Employee { ID= 1001, Name = "Priyanka", Salary = 80000 }, new Employee { ID= 1002, Name = "Anurag", Salary = 90000 }, new Employee { ID= 1003, Name = "Preety", Salary = 80000 } }; // In the following statement, the LINQ Query is executed immediately as we are // Using the Count() method which is a greedy operator which forces the query // to be executed immediately var result = (from emp in listEmployees where emp.Salary == 80000 select emp).Count(); // Adding a new employee with Salary = 80000 to the collection listEmployees // will not have any effect on the result as the query is already executed listEmployees.Add(new Employee { ID = 1004, Name = "Santosh", Salary = 80000 }); // The LINQ query is executed at the time of its creation. // This is proved because Santosh is not included in the count Console.WriteLine($" Employees with Salary 80000 : {result}"); Console.ReadKey(); } } }
Output:
Characteristics of Immediate Execution:
- The query is executed, and the results are obtained immediately, not when the results are iterated.
- Methods like ToList(), ToArray(), Count(), Average(), and others force immediate execution.
Advantages of LINQ Immediate Execution:
- Certainty: You get the results immediately, which can be useful if the data source changes.
- Simplified Debugging: It can be easier to debug queries that execute immediately.
Choosing Between Them
Use deferred execution when:
- The data source is large, and you want to delay execution to optimize performance.
- You want to modify the query or the source data before the query is actually executed.
Use immediate execution when:
- You need the results right away for further processing.
- The data source might change, and you want to work with a snapshot of the data.
Understanding the difference between deferred and immediate execution helps write more efficient LINQ queries and manipulate data more effectively in C#.
In the next article, I will discuss the ToList and ToArray Methods in C# with Examples. In this article, I explain the difference between LINQ Deferred Execution vs Immediate Execution using C# with Examples. I hope you understood the LINQ Deferred Execution vs Immediate Execution using C#.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.