Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

THREE Examples of Deferred vs. Immediate Execution in LINQ using C#

4.71/5 (7 votes)
5 Dec 2013CC (ASA 3U)4 min read 30.1K  
Three examples of deferred vs. immediate execution in LINQ using C#

Introduction

In the .NET world, we have Language-Integrated Query (LINQ) – it extends powerful query capabilities to the language syntax of C# and Visual Basic.

LINQ provider assemblies enable the use of LINQ with .NET Framework collections, SQL Server databases, ADO.NET Datasets, and XML documents. They are part of .NET framework 3.5 and above.

Now let’s look at three ways to understand what exactly is this deferred and immediate execution all about in LINQ using C#.

DateTime to Verify Deferred Execution of LINQ Query

  • Create console application with name “LinqSample
  • Create Product class with ID, Name, InStock members in it.
  • Create collection of products, LINQ Query and iterate through it to display time.

product-class-collection

Creating PRODUCT class and its sample collection
  • Now we will be creating two simple LINQ queries which will act as deferred and immediate query

deferred and Immediate execution

Queries to use for deferred and Immediate execution

We have created list of products, written query for deferred and immediate execution. Now let’s loop through them in 3 different foreach loops to check difference in time they are executed.

The yellow lines indicate that once the immediate query gets executed, any subsequent looping will fetch the same copy. While deferred execution gets executed for every loop showing different time stamp.

compare-deferred-immediate
Console output showing time stamp for Deferred & Immediate query execution

Collection Items Update to Show Deferred Execution & Immediate Execution

Adding the items to collection in execution and looping them again is also easiest way to check when LINQ query executed.

We have to write a query which gets only In Stock products, loop through that query, add one more item to collection and loop through again. The below code snippet image clearly shows this:

codesnippet-deferred-query
Code snippet showing additional product gets added to collection after query formed for Deferred execution

This code snippet below shows that we are doing the same thing except converting result to TOLIST along with query.

codesnippet-immediate-query
Code snippet showing additional product gets added to collection after query formed in Immediate execution

Now let’s compare both results after running the console application. Milk product added later is shown in deferred execution only. This is shown as yellow lines in screen shot.

compare-screenshot-collection
Deferred execution shows that even if collection changes, looping always result in fresh data

Is ToList() the Only Way to Force Immediate Execution?

No, it’s one of many methods that forces immediate execution. Here is the extract from MSDN on Immediate query execution:

In contrast to the deferred execution of queries that produce a sequence of values, queries that return a singleton value are executed immediately. Some examples of singleton queries are Average, Count, First, and Max. These execute immediately because the query must produce a sequence to calculate the singleton result. You can also force immediate execution. This is useful when you want to cache the results of a query. To force immediate execution of a query that does not produce a singleton value, you can call the ToList method, the ToDictionary method, or the ToArray method on a query or query variable.

Debugging LINQ Query to Show Deferred & Immediate Execution

Let’s use the above queries to debug console application. This is animated GIF to show debugging process.

debug-linq-csharp
Animated GIF file to show debugging steps of LINQ query

Let me summarise what is happening while debugging...

At first break point:

  • Deferred query is formed; it’s not executed as we can see that it only shows WhereSelectListIterator.
  • With the help of F11 key, am “Step Into” debugging; at first for each loop, the execution pointer going to where condition in query “where d.InStock == true”.
  • It does same looping, checking where condition for all items in product list and keeps them displaying on the console.

At second break point:

  • Immediate query is formed with ToLIST(), it immediately shows count as 5 before looping into foreach loop.
  • Even when it’s iterating through foreach loop, execution pointer never goes to where condition in query. It just prints out selected product on console.

In C#, the deferred execution is supported by directly using the yield keyword within the related iterator block. The below table lists the iterators in C# that use the yield keyword to ensure the deferred execution.

Method Iterator
CastCastIterator
ConcatConcatIterator
DefaultIfEmptyDefaultIfEmptyIterator
DistinctDistinctIterator
ExceptExceptIterator
GroupJoinGroupJoinIterator
IntersectIntersectIterator
JoinJoinIterator
OfTypeOfTypeIterator
RangeRangeIterator
RepeatRepeatIterator
ReverseReverseIterator
SelectSelectIterator
SelectManySelectManyIterator
SkipSkipIterator
SkipWhileSkipWhileIterator
TakeTakeIterator
TakeWhileTakeWhileIterator
UnionUnionIterator
WhereWhereIterator
ZipZipIterator

Happy coding with LINQ !!

The post THREE examples of Deferred vs. Immediate execution in LINQ using C# appeared first on Mithunvp.com.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-Share Alike 3.0 Unported License