Wednesday, 28 November 2012

Creating Chess Board Layout Using Pixel Manipulation in HTML5 Canvas


The canvas element in HTML5 can be used to render any graphical content. Shapes, paths, text and even images can be drawn on canvas. Canvas doesn’t support animations, but animations can be created by writing some additional JavaScript code.

Using the pixel manipulation feature of canvas, we can draw images or change colours of existing images. To manipulate pixels, we have to follow the following steps:
  • Create an image data object to draw on the canvas context
  • Loop through each pixel in the area to be drawn
  • Set RGBA values to current position inside the loop
  • Put the image on the canvas context

To draw something specific, we have to logically divide the area to be drawn and manipulate carefully. With this understanding, let’s start drawing a chess board layout.

Create a new HTML page and add a canvas element to the body.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Chess board layout using HTML5 Canvas</title>
</head>
<body>
    <canvas id="chessLayoutCanvas" width="320" height="320" >
        Sorry, your browser doesn't support Canvas!
    </canvas>
</body>
</html>

This is the entire HTML needed for this demo. To draw image on it, we have to write some JavaScript code. Following operations have to be performed inside the JavaScript code:
  • Obtain JavaScript object of the canvas element
  • Get the canvas context
  • Follow steps to draw image

Canvas element will be ready to operate once the entire page is loaded. So, above operations have to be performed once the page is loaded. Following script gets the canvas object and object of the 2-dimensional context:

var canvas = document.getElementById('chessLayoutCanvas');
if(!canvas || !canvas.getContext)
 return;
var context = canvas.getContext('2d');
if(!context || !context.putImageData)
 return;

To draw on the canvas, we have to get an image data object. Canvas context has a function createImageData that returns the object we need, but it is not supported on all browsers. Following snippet shows different ways of obtaining an object using which we can draw some colors on the canvas:
var chessLayoutImage, width, height;
width = canvas.width;
height = canvas.height;
            
if (context.createImageData) {
    chessLayoutImage = context.createImageData(width, height);
}
else if (context.getImageData) {
    chessLayoutImage = context.getImageData(0, 0, width, height);
}
else {
    chessLayoutImage = { 'width': width, 'height': height, 'data': new Array(width * height * 4) };
}

Now that we have the object using which we can achieve what we have to do, let’s think about the logic to draw a chess board layout.

As we all know, a chess board has alternate arrangement of white and black colors. On observing a bit, we can say that the color of last cell on a row is repeated on first cell of next row. Keeping this point in mind and calculating pixels on which we have to draw, I came up with the following logic:
var pixels = chessLayoutImage.data;
var isBlack=true;
for(pixelPosition = 0; pixelCount = pixels.length, pixelPosition < pixelCount ; pixelPosition+=4){
    if(pixelPosition%160==0 && !(pixelPosition%(40*4*320)==0)){
        isBlack= !isBlack;
    }
    if(isBlack){
        pixels[pixelPosition]=0;
        pixels[pixelPosition+1]=0;
        pixels[pixelPosition+2]=0;
        pixels[pixelPosition+3]=255;
    }
}
    
context.putImageData(chessLayoutImage,0,0);
context.strokeStyle='black';
context.strokeRect(0,0,320,320);
context.stroke();

If you observer the above code, I am drawing the black color alone. Place to be filled with white is left as by default the background is white.

After drawing the layout, a black border is drawn around the canvas to show the boundaries of the area.



Happy coding!

Saturday, 17 November 2012

Unit Testing Asynchronous methods using MSTest and XUnit

As we saw in previous posts, writing asynchronous code has become quite easy with .NET framework 4.5. To be able to write well and bug less code in any framework or language, unit tests play a vital role. Unit testing asynchronous code is a bit tricky and it is currently not supported by all unit test frameworks. In this post, we will see how to unit test an asynchronous method using MSTest and the XUnit framework.

Irrespective of the unit testing framework used, the test method written to test the asynchronous method has to follow a set of rules.
  • Test method should be marked as async
  • await keyword should be used while calling the method to be tested
  • Return type of the test method should be Task

I will be using the following asynchronous method for unit testing. It is a very simple method (I have used it in my post on Asynchronizing a C# method using async and await), that divides two numbers with a delay of 2 seconds.
public class ArithemticOperations
{
    public async Task<double> DivideAsync(int first, int second)
    {
        await Task.Delay(2000);
        return (double)second / first;
    }
} 

Unit testing using MSTest

MSTest is the testing framework built into Visual studio. If you are familiar with it, then testing asynchronous method doesn’t require much learning. If you are not already familiar with MSTest, you may go through Unit Testing Framework portion on MSDN.

Testing an asynchronous method is much similar to testing a synchronous method. We just need to follow the rules mentioned above. Following is a test class that tests the divide method created above.
[TestClass]
public class AsyncMethodUnitTests
{
    [TestMethod]
    public async Task DivideAsync_Returns_RightResult()
    {
        int first = 10, second = 20;
        double expected = 2.0;
        ArithemticOperations operations = new ArithemticOperations();
        double actual = await operations.DivideAsync(first, second);
        Assert.AreEqual(actual, expected);
    }
}


Unit testing using XUnit

XUnit is created by James Newkirk and Brad Wilson. It is built to support Test Driven Development with a design goal of simplicity. You may visit the Codeplex site of XUnit to learn more about it.

Testing asynchronous code using XUnit is very straight forward. Following is a test class that tests the divide method:
public class AsyncTests
{
    [Fact]
    public async Task AsyncDivide_Returns_RightResult()
    {
        int first = 10, second = 20;
        double expected = 2;
        ArithemticOperations operations = new ArithemticOperations();
        double actual = await operations.DivideAsync(first, second);
        Assert.Equal(actual, expected);
    }
}

Along with making your code run better by applying asynchronous strategies, you can unit test and even test drive them.

Happy coding!

Asynchronous controller actions in ASP.NET MVC 4

In this post, let’s continue our discussion on asynchronous programming in .NET 4.5 with ASP.NET MVC4. We will see how to create asynchronous controller actions in ASP.NET MVC 4.

 As in case of pages and handlers ASP.NET web forms, it was not easy to create asynchronous controller actions in ASP.NET MVC till MVC 3. We had to derive the controller class from AsyncController and create async and completed methods for the controller action that performs asynchronous task. This is quite a bit of work to perform.

As ASP.NET MVC 4 runs on top of .NET framework 4.5, we can use the magical async and await keywords to simplify this process. Using these keywords, we can easily create asynchronous controller actions just like we created methods in earlier posts. Following is a sample implementation of a controller action method:

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        DataServiceClient client = new DataServiceClient();
        var cities = await client.GetCitiesAsync();
        return View(cities);
    }
}

 In the above code, we are calling a WCF service asynchronously. As a method marked as async must return a Task, the return type is modified to Task<ActionResult>.

Happy coding!

Wednesday, 14 November 2012

Asynchronous HttpHandlers in ASP.NET 4.5

HttpHandlers are responsible to handle all types of HTTP requests that an ASP.NET web server receives. Page is also an HttpHandler, as it is derived from IHttpHandler interface.

Need of creating an HttpHandler may arise when we want to have more control over the way a request is handled. There can be scenarios where we have to generate some content dynamically like a captcha image to show on a page or generate some file that the user will download. In such cases, HttpHandler is the choice we stop at.

The HttpHandler may perform operations like fetching data from a remote location (like service calls, heavy DB queries) and some I/O operations on the disc. As sever would take considerable amount of time to complete such requests, it is better to perform them asynchronously.

To create an asynchronous HttpHandler in older versions of ASP.NET, the handler class has to be derived from IHttpAsyncHandler and implement its members. In ASP.NET 4.5, this process is simplified with the abstract class HttpTaskAsyncHandler. It has an abstract method ProcessRequestAsync, returning a Task. We can use the magical async and await keywords inside this method.

Following is a sample implementation an HttpHandler derived from HttpTaskAsyncHandler:

public class AsyncHandler : HttpTaskAsyncHandler
{
    public override async Task ProcessRequestAsync(HttpContext context)
    {
        //Calling a service to fetch data
        var client = new DataServiceClient();
        var getCitiesTask = client.GetCitiesAsync();

        //Setting folder path and file name
        string folderPath = context.Server.MapPath("Downloadables");
        string fileName = "cities.xlsx";

        //Asynchronously calling a method to store data obtained from service in an excel file
        await Task.Factory.StartNew(() => FillDataIntoExcel(getCitiesTask.Result, folderPath, fileName));

        //Sending the excel file to user's system
        context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        context.Response.WriteFile(folderPath + "\\" + fileName);
    }
}

You can download the complete source code of the handler here: Download Source. The sample application also contains implementation of an asynchronous web form.

Happy coding!

Sunday, 11 November 2012

Asynchronous pages in ASP.NET 4.5

In my previous post, we discussed the importance of asynchrony in ASP.NET applications. Before that, I blogged about using asynchrony in C# 5 and calling WCF services asynchronously using features in C# 5. In this post, we will learn how to create an ASP.NET web forms page that performs some asynchronous operations.

To make a page asynchronous in earlier versions of ASP.NET, the page has to implement the interface IHttpAsyncHandler and define concrete definitions to all the methods declared in the interface. This takes considerable amount of time and effort to make the page asynchronous.

In ASP.NET 4.5, we can turn the execution of any operation asynchronous by using async and await keywords. Any new page added to an ASP.NET application is considered synchronous by default. We can change this by setting value of Async property of the Page directive to true. Once this property is set, we can use async and await keywords in any method in the code behind file.

<%@ Page Language="C#" AutoEventWireup="true" Async="true" CodeBehind="Default.aspx.cs" Inherits="Async.Default" %>

This is because, performing asynchronous operations at wrong time may lead to some dangerous conditions on the server. By setting the Async attribute of the page, we are telling the server that, the current page is a safe place to perform async operations. Following is a sample page load event handler that calls a WCF service asynchronously and binds data to a GridView:
protected async void Page_Load(object sender, EventArgs e)
{
    var client = new DataServiceClient();
    var gettingCities = await client.GetCitiesAsync();
    gvCities.DataSource = gettingCities;
    gvCities.DataBind()                                                  
}

Following are the set of steps performed when ASP.NET detects the await keyword in the above event handler:
  • Continues executing other synchronous tasks of the life cycle event
  • Once the above step is finished, the underlying synchronization context fires up an event saying that an async operation is pending
  • ASP.NET waits asynchronously till the pending task is completed and then it continues executing the rest of the statements
  • With above step, the life cycle (page load in this case) event is over. The control goes ahead to the next life cycle event


There is another way to achieve this. It is shown in the following snippet:
protected void Page_Load(object sender, EventArgs e)
{
    RegisterAsyncTask(new PageAsyncTask(async () =>
    {
        var client = new DataServiceClient();
        var gettingCities = await client.GetCitiesAsync();
        gvCities.DataSource = gettingCities;
        gvCities.DataBind();
    }));                                                                                    
}

The advantage of performing async operation this way over what we did earlier is that, it registers an asynchronous handler with the page and now the execution is not dependent on the synchronization context. Execution of the statements in the PageAsyncTask passed in is not dependent on page the page life cycle event. So, ASP.NET will not wait asynchronously after executing rest of the logic in the life cycle event. It would rather continue execution with the next life cycle event handlers. Statements in the registered task are performed whenever the dependent operation is finished.

Note that, we used the async keyword with a lambda expression. It is legal in .NET 4.5, because lambda is meant to create a single cast delegate with an anonymous method. To make the method executable asynchronously, we can use async and await with lambda.

Further learning: Async in ASP.NET talk from AspConf 2012

Happy coding!

Saturday, 3 November 2012

Need of Asynchrony in ASP.NET

If you are following this blog, you might have observed that I am currently exploring asynchronous programming. Being web developers, it is important for us to understand how asynchrony will help the web applications we develop.

Let’s take an example

Say, we have a banking web application where the user wants to get the details of all the transactions he made during last two months in the form of an excel sheet. If the user would have performed some hundreds of operations during this period, the server operation will take considerable amount of time as it has to perform the following operations:
  • Fetch details of all transactions into memory
  • Create an excel file with appropriate columns
  • Write data into the excel file
  • Send it to the user across the network

Please note that this set of operations is performed in response to a single request. Technically, we can say that these four operations include the following set of heavy tasks:
  • Querying database to fetch details of hundreds of transactions
  • Creating a file on the disk
  • Writing data from an object into file
  • Sending file to the user’s system

As it is a banking application which is usually accessed by a large number of viewers, it is very important to serve them quickly. If there are hundreds of such requests, the server may respond very slowly to most of the users.

How does the server respond to a request?

In a typical ASP.NET web application, the server performs the following tasks when it gets a request:
  • Picks up a thread from CLR managed thread pool on and assigns the new request to it
  • The assigned thread performs all the tasks one by one. It works for the same request till all tasks of the request are completed
  • The thread is returned to thread pool as soon as it finishes the assigned tasks

So, the request is processed in a single-threaded model. If any task of the thread is halted for an I/O operation or a network call or any such request to complete, the corresponding thread is remains idle till the task gets required input. Waiting time of thread may be some milliseconds. Imagine a case when all threads are engaged and some of them are waiting because of heavy operations. If a new request hits the server now, it will have to wait until a thread is freed to process its request.

How can it be improved?

Performance of the web application described above will improve if the thread attached to a waiting request is used process some other request. Once the request receives response from the operation it was waiting for, processing of the request is resumed with help of a free thread from the CLR thread pool.

This can be achieved using asynchronous programming on the server side. We can use the asynchronous language features of C# or VB.NET to enhance such applications. You might have questions in your mind about the implementation of asynchrony in ASP.NET. We will discuss about them in subsequent posts.

Happy coding!

Tuesday, 30 October 2012

Calling WCF Services asynchronously using async and await

In my previous post, I covered how to use async and await keywords in C# 5 to create asynchronous methods. This post is a continuation of asynchronous programming, in which I will cover how to call WCF services from a client program using async and await.

Response of an application will be slower when it includes heavy weight operations like running complex queries against database, reading a piece of data from a file, calling a service to get some data or any remote operation. When such operations are performed synchronously, the application will be halted till the operation gets over. If we assign the slower operation to a separate task, the thread will be free to perform some other operation till the operation responds.

When a WCF service is called synchronously, the thread associated with the operation is idle till the response is obtained from the server. To avoid this in earlier versions of .NET framework (4.0 or earlier), we had an option to create asynchronous methods with an associated event. Using .NET 4.5, we can create task-based proxies while adding service reference to an application. This can be done using by clicking on the Advanced button in the Add Service Reference dialog.


Add Service Reference

On the Service Reference Settings dialog, check Allow Generation of asynchronous operations and Generate task-based operations.




Please note that this feature is available in .NET framework 4.5 onwards. i. e., to be able to generate task-based asynchronous proxies, target version of the project to which we are adding the service reference should be 4.5 or above.

For example, say a WCF service contains GetAllEmployees method, which returns a collection of Employees. Following snippet shows signature of the method:
List<Employee> GetAllEmployees();

If reference of this service is added to a client application written .NET 4.5 with task-based operations enabled, then you will be able to find the following two proxies in the generated Reference.cs file for the above method:
Public EmployeeServiceReference.Employee[] GetAllEmployees() {
    return base.Channel.GetAllEmployees();
}
        
public System.Threading.Tasks.Task<EmployeeServiceReference.Employee[]> GetAllEmployeesAsync() {
    return base.Channel.GetAllEmployeesAsync();
}

First proxy is the synchronous proxy and second one is the task-based proxy. We can call the WCF service asynchronously using the second proxy.

As we discussed in the previous post, any method that returns a Task can be called using await. In a client application, the method GetAllEmployeeAsync can be called using await keyword. Following is a sample method calling the service asynchronously:
async void LoadDataFromService()
{
    EmployeeServiceClient client = new EmployeeServiceClient();
    var getEmployeesTask = client.GetAllEmployeesAsync();
    Employees = await getEmployeesTask;
}

Happy coding!

Sunday, 28 October 2012

Asynchronizing a C# method using async and await

In the business applications that we build as part of our job consist of several heavy weight operations like file manipulations, dynamically creating images, generating an excel file from a result set and the list goes on.

In such scenarios, we cannot let our application to halt till the requested operation is completed, as the operation takes a lot of time. What we can do is, assign the heavier operation to a separate task and do something that is independent of result of the operation till the operation is completed.

I have a simple console application that consists of methods performing add and divide arithmetic operations. Sleep method is called in the Divide method to make the execution slow. Code of the console application is shown below:
static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
            
    int first = 5;
    int second = 10;

    Console.WriteLine(Add(first, second));
    Console.WriteLine(Divide(second, first));
    Console.WriteLine(Divide(second, first));

    watch.Stop();
    Console.WriteLine("Time taken: {0}",watch.ElapsedMilliseconds);
}

static int Add(int first, int second)
{
    return first + second;
}

static double Divide(int second, int first)
{
    System.Threading.Thread.Sleep(2000);
    return (double)second / first;
}

If you run the application, the value of watch.EllapsedMilliseconds would be around four seconds. This is because, we are calling the Divide method twice synchronously. The thread executing the application waits until the first method call is completed and the result is returned before proceeding to the second call.

We can reduce the time taken by this application using Task Parallel Library (TPL). We can create a Task for each of the slower operation and continue with other operations without waiting for the Tasks to finish. Following snippet shows how to create a Task and get the result once the task is finished.

var taskName = Task.Factory.StartNew<returntype>(() => MethodToCall(arguments));
//Perform other independent operations here
...
...
...
returntype variable = taskName.Result;

Let’s use this feature in the demo application. Create two tasks, one for each division call and use the result to print it on the screen. Replace the statements displaying results on the console with the following statements:
var divisionTask = Task.Factory.StartNew<double>(() => Divide(second, first));
var secondDivisionTask = Task.Factory.StartNew<double>(() => Divide(second, first));
Console.WriteLine(divisionTask.Result);
Console.WriteLine(secondDivisionTask.Result);
Run the application. Time taken now is around two seconds. So, the difference in time taken is significant. We may say that both the division tasks finish almost at the same time.

Though this approach reduced the time taken, it demands the programmer to create tasks manually and manage them. It might become quite difficult for us to manage an application that involves creating a large number of tasks. To avoid this problem, the C# language designers have added the async and await keywords. These keywords can be used in an application built using Visual Studio 2012 and targeted to .NET Framework 4.5.

A method performing a heavier or slower operation should be marked as async and the statement in that method that takes a lot of time to finish should be marked as await. The await keyword indicates that a slow operation is going to start. Once the currently running thread finds a statement marked with await, it goes to perform some other operation without waiting for the statement to complete. The await can be applied with a Task. For example, if a method call has to be marked as await, the method should return a Task.

Return type of an async method can be either void or Task. The C# compiler generates a bunch of code when an async method is compiled. It in turn uses the Task Parallel Library.

Following is the modified Main method and the Divide method using the async and await keywords:
static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();

    int first = 5;
    int second = 10;
            
    Console.WriteLine(Add(first, second));
    var divisionTaskAsync = DivideAsync(second, first);
    var secondDivisionTaskAsync = DivideAsync(second, first);
    Console.WriteLine(divisionTaskAsync.Result);
    Console.WriteLine(secondDivisionTaskAsync.Result);
            
    watch.Stop();
    Console.WriteLine("Time taken: {0}", watch.ElapsedMilliseconds);
}

static async Task<double> DivideAsync(int second, int first)
{
    await Task.Delay(2000);
    return (double)second / first;
}

Call to Thread.Sleep is replaced with Task.Delay as the later returns a Task. I renamed the Divide method to DivideAsync just to follow the convention that is already used by the framework methods. Otherwise, it doesn’t make any difference.

Happy coding!

Saturday, 20 October 2012

How ASP.NET 4.5 Model Binding and IQueryable work behind the scenes

Model Binding is a nice new feature added to ASP.NET 4.5. Using this feature, we can bind data to controls in a type-safe way. This means, the properties of the data are known at the compile time.

If a method returning IQueryable type of collection is bound to a GridView, paging and sorting can be enabled by applying some simple configurations. There is no need of writing any extra amount of code to handle paging or sorting.

But, the question here is, how does that work? Is it a magic? The answer is very simple: dynamic nature of IQueryable. IQueryable operators can be invoked dynamically.

Following is signature the Where operator of IQueryable:
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
Second parameter of the operator is of Expression<Func> type. The difference between a Func and an Expression is Func is a delegate whereas Expression is a data structure. This means, the contents of an Expression can be parsed and inspected. This also means that, if we have every piece of information that an Expression needs, we can build it dynamically. Have a look at the inputs that the other IQueryable operators take, they all accept Expression types.

For instance, say following is the GridView used on an ASP.NET web form:
<asp:GridView runat="server" AutoGenerateColumns="false" ID="gvCustomers" 
        ItemType="WhatsNewInAspNet45.DataAccess.Customer" DataKeyNames="CustomerID" SelectMethod="GetCustomers" AllowPaging="true" PageSize="10"         AllowSorting="true">
        <Columns>
            <asp:TemplateField HeaderText="Company Name" SortExpression="CompanyName">
                <ItemTemplate>
                    <%#: Item.CompanyName %>
                </ItemTemplate>
            </asp:TemplateField>
      ...
      ...
</asp:GridView>
Following is a simple implementation of the GetCustomers method:
public IQueryable<Customer> GetCustomers()
{
    return _Context.Customers;
}
When the page containing this GridView is viewed on a browser, the user interacting with the page can sort the data based on data in a column and also can navigate through different pages of the GridView. When we click on a column of the GridView to sort the data, SortExpression of the column will be picked up and it will be used in the OrderBy operator of IQueryable to fetch data. As GetCustomers returns IQueryable type of data, we may say that, result of the following statement is used to bind data to the GridView:
GetCustomers().OrderBy(c=>c.CompanyName);

Digging a bit more, we may say that, the following LINQ query is evaluated:
_Context.Customers.OrderBy(c=>c.CompanyName);

If the SelectMethod GetCustomers uses Entity Framework or LinqToSQL, the SQL query that will be formed to hit the database because of the above LINQ query would contain an order by clause. Otherwise, if the data is fetched from a WCF Data Service, the URL formed to invoke the service would contain an order by expression.

Reason behind this behaviour is deferred execution of LINQ queries. They get executed when they are needed. We require data before it is bound to a user interface control. Till then, the query will not be parsed.

Similarly, if we navigate to any page on the GridView, Skip and Take operators are applied on the result of select method to fetch the data that should appear on the target page. If SelectMethod returns any other type of data (i.e., other than IQueryable), we need to write logic for fetching appropriate data and returning it to the target control.

Happy coding!

Tuesday, 16 October 2012

Basics: Understanding Lambda Expression

If you are following my blog, I have been writing posts on latest technologies, concepts and some of the issues that I faced with their solutions. I decided to put some posts on basic some concepts intermittently. This is the first post of the never-ending basics series.

I often hear from people that lambda expression does a magic behind the scenes which is hard to understand. I agree that it works magically, but the magic is not hard to understand. When I saw lambda expression for the first time, one of my friends told me that it is a delegate. Then I tried to understand how it is a delegate and how does it work behind the scenes.

With my understanding of creating delegates with anonymous methods, I thought that when we write a lambda expression, we are defining an anonymous method and assigning it to a delegate object without using .NET’s delegate keyword.

Keeping the above point in mind, I started writing a small Console Application to move from a delegate with a named method attached to it to lambda expression. I wrote a method that checks if a number is positive and returns a Boolean value and declared a delegate to hold methods of similar signature:
delegate bool PositiveTest(int number);
bool CheckIfPositive(int number)
{
    return number > 0;
}

Step 1: Instantiating and invoking the delegate using a defined method:
PositiveTest testDelegate = new PositiveTest(CheckIfPositive);

Step 2: Instantiating delegate using anonymous method and the delegate keyword:
PositiveTest testAnonymousDelegate = delegate(int number)
{
    return number > 0;
};

Step 3: Removing the delegate keyword and introducing =>:
PositiveTest delegateWithoutDelegateKeyword = (int number) =>
{
    return number > 0;
};

Step 4: Removing data type of the input parameter:
PositiveTest delegateWithDataTypeRemoved = number =>
{
    return number > 0;
};

Step 5: Removing curly braces and the return keyword:
PositiveTest delegateWithNoBracedNReturn = number => number > 0;

In the above listing, the amount of code written to instantiate a single cast delegate is gradually reduced. We moved from delegate accepting a defined method to delegate accepting an expression that doesn’t have types or curly braces. I hope, now you feel comfortable with lambda expression if you had any confusion earlier.

Happy coding!