Showing posts with label Lambda Expressions. Show all posts
Showing posts with label Lambda Expressions. Show all posts

Monday, September 11, 2017

Closures and Race Conditions

Closure = code + supporting data environment

int x = 123;

Task. Factory.StartNew( () =>
{
    x = x + 1;
}
);
...
Console.WriteLine(x);

In the example above x is called a closure variable. The compiler has to figure out how to pass the value x to the lambda expression. The compiler does this By Reference, not by value. Think of By Reference as pointers to the same memory space for the shared variable x.

So, everywhere you see x in the above example it all references the same x. This means if x is changed anywhere by any of the code including the one if the separate thread we have a race condition (since the variables are read and written).

The program could either print out 123 or 124 depending on which thread finishes first. The result is not consistent.

This means we need to take steps to make sure only one thread is read or writing the variable at a time.

Behind the scenes

The compiler will generate the following code for the code above


private sealed class c__DisplayClass2
{
public int x;
public void b__0()
{
this.x = this.x + 1;
}
}

cgobj = new c__DisplayClass2();
cgobj.x = 123;
delegate = new Action(cgobj.b__0);
Task.Factory.StartNew(delegate);
...

Console.WriteLine(cgobj.x);

Reference

Content is based on Pluralsight video called Introduction to Async and Parallel Programming in .NET 4 by Dr. Joe Hummel. 

Lambda Expression

With Parameters

A method is a named block of code

public void DoSomething(parameters)
{
    code...
}

Lambda expression = unnamed block of code

They are easy to identify because they have a => in the statement to identify the lambda expression.

(parameters) => 
{
     code...
}

No Parameters

A method with NO parameters would look like this

public void DoSomething()
{
    code...
}

The lambda expression would look like

() => 
{
     code...
}


Behind the scenes

Lambda express = custom class and delegate

The compiler will create a class with an arbitrary name and a method with an arbitrary name and implemented with the same signature as the lambda expression.

Actions

You can think of Actions as pointers to methods.
An Action is an instance of a delegate.
When you see a signature for a method that requires a parameter that is of type Action what it is asking for is a lambda expression.

NOTE: To create an Action you can also use a method as shown below.
Action action = new Action(DoSomething());

Reference

Content is based on Pluralsight video called Introduction to Async and Parallel Programming in .NET 4 by Dr. Joe Hummel.