Showing posts with label Async programming. Show all posts
Showing posts with label Async programming. Show all posts

Tuesday, December 5, 2017

Waiting on multiple C# .Net awaits

Introduction

Async and Await makes developers life easy without the callback hell in asynchronous programming. But it is equally harmful, if it is in the hands of typewriting coders. Mainly those who don't know how things are working can use async and await in wrong way. This post examines one of such scenario and how to avoid it.

Lets consider the below example. There are 2 independent web service calls to be made and once result is available, do some operation using the results from both the async calls.

private static async Task<string> GetFirstTask(HttpClient client)
{
            Log(nameof(GetFirstTask));
            return await client.GetStringAsync("http://httpbin.org/drip?numbytes=3&duration=3&code=200");
}
private static async Task<string> GetSecondTask(HttpClient client)
{
            Log(nameof(GetSecondTask));
            return await client.GetStringAsync("http://httpbin.org/drip?numbytes=6&duration=6&code=200");
}
private void Process(string first, string second)
{
            Log($"{nameof(Process)} - Length of first is {first.Length} & second is {second.Length}");
}
private static void Log(string msg)
{
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}, Time {DateTime.UtcNow.ToLongTimeString()}, Message {msg}");
}

The first 2 methods returns 2 generic Task<string>. The URL is using httpbin.org which is a hosted service for testing purpose. The duration in the query string controls the delay. Meaning the response will be coming after that duration. Just to avoid Thread.Sleep(). The Process() just display it's parameters.

The normal way

Below is the code we can see more from new async await users.

async internal Task TestNormal_TheBadMethod()
{
    HttpClient client = new HttpClient();
    string firstrequest = await GetFirstTask(client);
    string secondrequest = await GetSecondTask(client);

    Process(firstrequest, secondrequest);
}

The output might be something like below.

Thread 1, Time 8:47:00 PM, Message GetFirstTask
Thread 9, Time 8:47:02 PM, Message GetSecondTask
Thread 7, Time 8:47:07 PM, Message Process - Length of first is 3 & second is 6

Problem

The line where GetFirstTask() is called will wait till the result is obtained. ie wait for 3 seconds to get response from web service. The second task will start only the first is completed. Clearly sequential.

await at method invocation

This is another way developers try.

async internal Task TestViaAwaitAtFunctionCall_StillBad()
{
    Log(nameof(TestViaAwaitAtFunctionCall_StillBad));
    HttpClient client = new HttpClient();
    Process(await GetFirstTask(client), await GetSecondTask(client));
}

Output will look as follows.

Thread 1, Time 8:49:22 PM, Message GetFirstTask
Thread 7, Time 8:49:25 PM, Message GetSecondTask
Thread 9, Time 8:49:30 PM, Message Process - Length of first is 3 & second is 6

Problem

In other languages await keyword at function invocation might make it parallel. But in C# its still sequential. It wait for first await and then process second.

Making it run parallel

So what is the solution? Both the Tasks should be created before we wait for their results. So those tasks will run in parallel. Once await is called, they just give the result if available or wait till the result is available. So the total time is the highest time, not sum of all wait times. Below code snippets does it.

private async Task TestViaTasks_Good()
{
            Log(nameof(TestViaTasks_Good));
            HttpClient client = new HttpClient();
            Task<string> firstrequest = GetFirstTask(client);
            Task<string> secondrequest = GetSecondTask(client);
            Process(await firstrequest, await secondrequest);
}

Output looks below.

Thread 1, Time 8:55:43 PM, Message GetFirstTask
Thread 1, Time 8:55:43 PM, Message GetSecondTask
Thread 8, Time 8:55:48 PM, Message Process - Length of first is 3 & second is 6

Here the Tasks are created before any waits are places on them. So they worked in parallel.

Will this work when second call dependent on first call's result

Not at all. Because the second call cannot start without the result from first call. So this has to be sequential.

More reading

https://stackoverflow.com/questions/33825436/when-do-multiple-awaits-make-sense
https://stackoverflow.com/questions/36976810/effects-of-using-multiple-awaits-in-the-same-method

Tuesday, November 14, 2017

C# async and await with Thread static

This is continuation of below post about async and await. That post discuss about how the async and await evolved and the basics. The same sample context is used in this post as well. So better read below post before continuing.

http://joymonscode.blogspot.com/2015/06/c-async-and-await-programming-model.html

Async Await and calling thread behavior

There is no objection that it simplified the reasoning about the code. But it may cause trouble, if we implement without understanding how it works. Let us see one example below.

public void Main()
{
           Console.WriteLine($"Main() - Thread Id - {Thread.CurrentThread.ManagedThreadId}");
           for (int counter = 1; counter < 5; counter++)
           {
               if (counter % 3 == 0)
               {
                   WriteFactorialAsyncUsingAwait(counter)
               }
               else
               {
                   Console.WriteLine(counter);
               }
           }
}
private async Task WriteFactorialAsyncUsingAwait(int facno)
{
    Console.WriteLine($"WriteFactorialAsyncUsingAwait() - Thread Id - {Thread.CurrentThread.ManagedThreadId} - Begin");
    int result = await Task.Run(()=> FindFactorialWithSimulatedDelay(facno));
    Console.WriteLine($"WriteFactorialAsyncUsingAwait() - Thread Id - {Thread.CurrentThread.ManagedThreadId} - Factorial of {facno} is {result}");
}


Guess what would be the thread ids printed from WriteFactorialAsyncUsingAwait(). Will those be same?

Those who says same, be prepared to spend nights and weekend debugging. Especially if you have something ThreadStatic before and after await. Below goes the output.

Main() - Thread Id - 1
1
2
WriteFactorialAsyncUsingAwait() - Thread Id - 1 - Begin
4
WriteFactorialAsyncUsingAwait() - Thread Id - 3 - Factorial of 3 is 6

In the code the await is executed in separate thread similar to its Task<> equivalent

Thread.ContinueWith and calling thread behavior

 Lets see what is its Task<> based implementation.

public void Main()
{
    Console.WriteLine($"Main() - Thread Id - {Thread.CurrentThread.ManagedThreadId}");
    for (int counter = 1; counter < 5; counter++)
    {
        if (counter % 3 == 0)
        {
            WriteFactorialAsyncUsingTask(counter);
        }
        else
        {
            Console.WriteLine(counter);
        }
    }
    Console.ReadLine();
}
private void WriteFactorialAsyncUsingTask(int no)
{
    Console.WriteLine($"WriteFactorialAsyncUsingTask() - Thread Id - {Thread.CurrentThread.ManagedThreadId} - Begin");
    Task<int> task=Task.Run<int>(() =>
    {
        int result = FindFactorialWithSimulatedDelay(no);
        return result;
    });
    task.ContinueWith(new Action<Task<int>>((input) =>
    {
        Console.WriteLine($"WriteFactorialAsyncUsingTask() - Thread Id - {Thread.CurrentThread.ManagedThreadId} - Factorial of {no} is {input.Result}");
    }));
}

See the output it is working the same way as of async await model.

Main() - Thread Id - 1
1
2
WriteFactorialAsyncUsingTask() - Thread Id - 1 - Begin
4
WriteFactorialAsyncUsingTask() - Thread Id - 4 - Factorial of 3 is 6

Why the consuming code is written inside ContinueWith({}) callback instead of reading the result from Task.Result property? If it is not via ContinueWith({}), the execution wait on task.Result line, hence the outer loop cannot move to next item. We loose all the benefits of Task then. Below goes the code for task.Result access and see how it blocks the outer loop from executing in parallel.



public void Main()
{
    Console.WriteLine($"Main() - Thread Id - {Thread.CurrentThread.ManagedThreadId}");
    for (int counter = 1; counter < 5; counter++)
    {
        if (counter % 3 == 0)
        {
            WriteFactorialAsyncUsingTask(counter);
        }
        else
        {
            Console.WriteLine(counter);
        }
    }
    Console.ReadLine();
}
private void WriteFactorialAsyncUsingTask(int no)
{
    Console.WriteLine($"WriteFactorialAsyncUsingTask() - Thread Id - {Thread.CurrentThread.ManagedThreadId} - Begin");
    Task<int> task=Task.Run<int>(() =>
    {
        int result = FindFactorialWithSimulatedDelay(no);
        return result;
    });
    Console.WriteLine($"WriteFactorialAsyncUsingTask() - Thread Id - {Thread.CurrentThread.ManagedThreadId} - End - Task Result - {task.Result}");
}

The output below shows clearly that the 4 is processed from the loop only after the 3 is processed. We lost the parallelism. The thread ids are same before and after.

Main() - Thread Id - 1
1
2
WriteFactorialAsyncUsingTask() - Thread Id - 1 - Begin
WriteFactorialAsyncUsingTask() - Thread Id - 1 - End - Task Result - 6
4

Moral of the story

Though async await seems easy to use, usage without understanding will take away our sleep and weekends.

Tuesday, June 30, 2015

C# async and await programming model from scratch

Introduction

This is a brief introduction to async and await keywords to a normal developer who wants to understand the basics and little insights to internals of how stuff works.

Background

Asynchronous programming is now an essential thing when we develop any application because it avoids waiting in main thread on long running operations such as disk I/O, network operations database access etc...In normal case, if our program needs something to be done from the results of these long operations, our code is struck until the operation is done and we proceed from that point. 

Using async mechanism, we can just trigger long running operations and can do other tasks. Those long running operations does the job in different thread and when they complete it, they notify our main code and our code can do the post actions from here. When we refer our code, its our main thread which deals with user interface or the thread which primarily process a web request. Sometimes we ourselves write these kind of long running operations.

What is async and await

In simple sense these are 2 new keywords introduced in .Net 4.5 to easily write asynchronous programs. They work in the method level. Of course we cannot make classes work in parallel as they are not unit of execution. 

Are these keywords known to CLR, the .Net run-time or a wrapper over TPL Task Parallel Library ? If they are wrappers, it it good to have language depends on a library written using same language?

We will find out the answer to these questions in this article.

History of .Net async programming

Threads were there from the very beginning of the .Net framework. They were the wrappers on operating system threads and little difficult to work with. Then more concepts such as background worker, async delegate and Task Parallel Library came to ease the async programming model. Those came as part of class library. C# language as such doesn't had 'out of the box' support for  async programming until the async and await keywords are introduced with C# 4.0. Lets see how the async and await helps us in async programming by examining each of these methods.

Example

Lets take the below example of finding factorial of first N numbers if they are completely divisible by 3. We are using console application for simplicity. If we had used a windows application we could easily hook into async event delegate handler and demo the async features in easily. But that won't help us to learn the language features.

Synchronous code


We can see there is a loop runs from 1 to 5 using counter variable. It find whether the current counter value is completely divisible by 3. If so it writes the factorial. The writing function calculates the factorial by calling FindFactorialWithSimulatedDelay() method. This method here in sample is going to put delay to simulate real life workload. In other sense this is the long running operation.

Easily we can see that the execution is happening in sequence. The WriteFactorial() call in loop waits until the factorial is calculated. Why should we wait here? Why can't we move to next number as there is no dependency between numbers? We can. But what about the Console.WriteLine statement in WriteFactorial(). It should wait until the factorial is found. It means we can asynchronously call FindFactorialWithSimulatedDelay() provided there is a call back to the WriteFactorial(). When the async invocation happens the loop can advance counter to next number and call the WriteFactorial().

Threading is one way we can achieve it. Since the threading is difficult and needs more knowledge than a common developer, we are using async delegates mechanism. Below is the rewrite of WriteFactorial() method using async delegate.

Making it async using async delegates

One of the easier method used earlier was to use Asynchronous Delegate Invocation. It uses the Begin/End method call mechanism. Here the run-time uses a thread from thread pool to execute the code and we can have call backs once its completed. Below code explains it well which uses Func delegate.

No change in finding factorial. We simply added new function called WriteFactorialAsyncUsingDelegate() and modified the Main to call this method from the loop.

As soon as the BeginInvoke on findFact delegate is called the main thread goes back to the counter loop, then it increment the counter and continue looping. When the factorial is available the anonymous call back will hit and it will be written into console.

We don't have direct option to cancel the task. Also if we want to wait for one or more methods its little difficult.

Also we can see that the piece of code is not wrapped as object and we need to battle with the IAsyncResult object to get the result back. TPL solves that problem too, It looks more object oriented. Lets have a look.

Improving async programming using TPL

TPL is introduced in .Net 4.0. We can wrap the asynchronous code in a Task object and execute it. We can wait on one or many tasks to be completed. Can cancel task easily etc...There are more to it. Below is a rewrite of our Factorial writing code with TPL.

Here we can see that first task is run then its continuing with next task which is the completed handler which receives notification of first task and writing the result to console.

Still this is not a language feature. We need to refer the TPL libraries to get the support. Main problem here is the effort to write the completed event handler. Lets see how this can be rewritten using async and await keywords.

The language feature async and await

We are going to see how the TPL sample can be rewritten using async and await keywords. We decorated the WriteFactorialAsyncUsingAwait method using async keyword to denote this function is going to do operations in async manner and it may contain await keywords. Without async we cannot await.

Then we are awaiting on the factorial finding function. The moment the await is encountered during the execution, thread goes to the calling method and resume the execution from there. Here in our case the counter loop and takes next number. The awaited code is executed using TPL as its task. As normal it takes a thread from the pool and execute it. Once the execution is completed the statements below the await will be executed.
Here also we are not going to change anything in the FindFactorialWithSimulatedDelay(). 

This avoids the needs for extra call back handlers and developers can write the code in a sequential manner.

What is the relation with Task Parallel Library and async await keywords

The keywords async and await make use of TPL internally. More clearly we can say async and await are syntactic sugar in C# language. Still not clear? In other sense the .Net runtime doesn't know about async and await keywords.

Look at the above disassembled code of  WriteFactorialAsyncUsingAwait(). I used reflector to disassemble the assembly.

Should a language depend on a library/class created with it?

This is a old question. If we look at C or C++, the language was always independent and the libraries were fully depend on it. But if we look from introduction of yield keyword in C#, we can see there is a marriage between language features (keywords) and libraries. Here yield which is a language feature depends on IEnumerable interface created using the language itself. Then the compiler does the magic and replace the yield keyword with corresponding IEnumerable implementation making sure CLR doesn't know about yield keyword.

Another example is using keyword. Its tightly coupled with IDisposable interface. Since then there are many syntactic sugars added more details can be found in below link.

http://blogs.msdn.com/b/ericlippert/archive/2010/10/28/asynchrony-in-c-5-part-one.aspx

Personally I don't prefer mixing language features with libraries. Let language evolve its own and libraries depend on language. If we do the other way the compiler is forced to inject more code and we know adding more lines is not coming in free. But unfortunately we are in a world where coding needs to be fast not the execution of the code.

Should the compiler modify our code?

The main problem with compiler modifying our code is debugging. There are chances that we will see call stack of our application which contains symbols which are not written by us. Try to see the call stack by raising an exception in anonymous method. If there are many anonymous methods in the application, that's it. We are done in debugging.

Should the language know parallel programming and threading?

This is another area to discuss. Since the threading is managed by OS, should the language care about threading. Should the threading be a library or integrated language feature?

Now a days most of the hardware has multiple cores and if the language doesn't provide the integrated features, nobody will leverage multiple cores. This is because either development community is afraid of threading or it requires additional coding time. If the language gives easy way, developers can focus more on the functionality or business side of the app than threading which is infrastructure related.

So I really want my language and associated runtime know parallel and async programming. But please try to avoid tight coupling with class library and stop compiler altering my code.

When should we use it?

We can use async and await anytime we are waiting for something. ie whenever we are dealing with async scenarios. Examples are file IO, network operations, database operations etc...This will help us to make our UI responsive.

So go ahead and make sure your APIs are await-able.

References

https://msdn.microsoft.com/en-us/library/hh191443.aspx
http://stephenhaunts.com/2014/10/10/simple-async-await-example-for-asynchronous-programming/
https://richnewman.wordpress.com/2012/12/03/tutorial-asynchronous-programming-async-and-await-for-beginners/

Monday, June 9, 2014

We can't eat all the .Net exceptions using try catch block especially ThreadAbortException

Background

It is generally not recommended in .Net to control the application flow by throwing and catching exception. But in some cases people does it, to safely do the thing. In one of the WCF component in my project there is one scenario where the application flow is controlled via exception. The main intention was to keep the exception inside the thread itself and return a wrapper which says there was exception or not. Below is the stripped down code just for understanding.

internal class LongRunningProcessCaller
{
    private delegate ResultWrapper InvokeAsync(bool parameter);
    public void Invoke()
    {
        InvokeAsync invoker = new InvokeAsync(CallInvokerThreadHandler);
        invoker.BeginInvoke(true, new AsyncCallback(InvokeAsyncCompleted), null);
    }
    private ResultWrapper CallInvokerThreadHandler(bool test)
    {
        try
        {
            LongRunningMethodWhichMayThrowThreadAbortException();
            return new ResultWrapper();
        }
        catch (Exception ex)//All the exceptions should be caught and pass via Error property
        {
            return new ResultWrapper() { Error = ex };
        }
    }
    private void InvokeAsyncCompleted(IAsyncResult result)
    {
        InvokeAsync asyncDelegate = (result as AsyncResult).AsyncDelegate as InvokeAsync;
        //This method will hang, if there is any exception in CallInvokerThreadHandler
        ResultWrapper invokerResult = asyncDelegate.EndInvoke(result);
        if (invokerResult.Error == null)
        {
            Console.WriteLine("Errored");
        }
        else
        {
            Console.WriteLine("Worked");
        }
    }
    private void LongRunningMethodWhichMayThrowThreadAbortException()
    {
        System.Threading.Thread.CurrentThread.Abort();
    }
}
class ResultWrapper
{
    public Exception Error { set; get; }
}

The problem

It went good for some time in production and slowly we started getting inconsistent issues from production. As it is inconsistent, we were not able to reproduce in dev machines and fix it. If we look at the code we can understand that inconsistent issue may happen, in case the catch inside CallInvokerThreadHandler() didn't eat and convert the exception properly.

The debug process

Since its using async delegate invocation mechanism we started thinking about exception behavior in threads and find nothing much. Then we put instrumentation code in catch block and pushed to environments where this issue is reproducing. This leads to investigation of ThreadAbortException which we were not expecting in normal course.

Further google about how to handle ThreadAbortException in IIS hosting environment, gives information only regarding the ASP.Net web sites related to Respose.Redirect. Some sites suggests to join the threads.
One says to resolve this exception, we can just increase maxConnections in web.config.

The Root cause

But our problem is different we have WCF service which calls another WCF service in different thread. The different thread is needed because the second WCF call is time consuming say 2-3 hours. Since the new thread is long running, there are chances for that to be aborted due to various reasons. Our aim should be to handle the failures properly. But what was the problem in the code listed above as it seems to be doing the purpose?

The root cause is, The ThreadAbortException  cannot be eaten by the catch block and we were relying on exception eating behavior.

So if the ThreadAbortException occurs the wrapping of the error result for returning to the completed handler will not work. The runtime will re throw the exception at the end of the catch which will make the EndInvoke in InvokeAsyncCompleted() to wait infinitely.

So rewrote the code as follows by avoiding the async completed handler.

internal class LongRunningProcessCaller
{
    private delegate ResultWrapper InvokeAsync(bool parameter);
    public void Invoke()
    {
        InvokeAsync invoker = new InvokeAsync(CallInvokerThreadHandler);
        invoker.BeginInvoke(true, null, null);
    }
    private ResultWrapper CallInvokerThreadHandler(bool test)
    {
        try
        {
            LongRunningMethodWhichMayThrowThreadAbortException();
            Console.WriteLine("Worked");
        }
        //All the exceptions should be processed here.
        //This is because the runtime rethrows ThreadAbortException from catch automatically.
        catch (Exception ex)
        {
            Console.WriteLine("Errored");
        }
    }    
    private void LongRunningMethodWhichMayThrowThreadAbortException()
    {
        System.Threading.Thread.CurrentThread.Abort();
    }
}

Happy coding...

Monday, May 19, 2014

Why the compilation error 'The "EnsureBindingRedirects" task failed unexpectedly'

Recently I moved to our company's US office located at New Jersey. When I moved to new office, I had to return my laptop to Kochi office. There was arrangement done to upload all my files to company's FTP server so that I can download once I get machine from US office.

When I got the new machine and compile one of my visual studio solution, it showed a wired compilation error as below. It was not associated to any of the projects inside the solution.

Error     66     The "EnsureBindingRedirects" task failed unexpectedly.
System.MissingMethodException: Method not found: 'System.String System.Reflection.AssemblyName.get_CultureName()'.
   at Roxel.BuildTasks.EnsureBindingRedirects.MergeBindingRedirectsForReferences()
   at Roxel.BuildTasks.EnsureBindingRedirects.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult)

The google says its because of missing culture name in web.config file. I corrected it, in one of the MVC web project in the solution but the issue still persisted. Then a deep google gave insight to async related dlls of Microsoft. 

At some point, I had installed a nuget package named 'Microsoft.Bcl.Async' which helps to use the async keyword in pre .Net 4.5 versions. I just removed that package and it started working. For me that solution is just a single place testing solution where it contains all types of projects so that I can try any kind of PoCs.

More details about fixing the issue are available in the below link.
http://blogs.msdn.com/b/bclteam/archive/2013/04/17/microsoft-bcl-async-is-now-stable.aspx?PageIndex=3

Monday, July 9, 2012

Asynchronous programming model in Node.JS

Sometime back I had attended a session conducted by K-MUG and one of the session was ‘How to integrate Node.JS with Windows Azure’. Shiju who is a MVP took the session really good and as the result I started learning the Node.JS technology.I am not the right person to talk about the technology and compare its merits with other existing technologies. But the idea of asynchronous event driven programming really interested me as that is something new,comparing with the existing programming approach.(I had worked with threads,events,callbacks etc…in .Net.But Node.JS seems fully leveraging the async)
Some points what I understood about Node.JS
  • It helps to write javascript at server side.
  • It has or starts its own webserver like IIS and Apache
  • Even IIS can relay the request to NodeJS (node.exe) via IISNode module.
  • NodeJS can be used to develop web sites as well as web services.
  • How Node will handle different protocols / compete with WCF is still confusing me. May be there will be extensions for handling that. Don’t ask why Node.JS need to support .Net specific remoting via net.tcp because I don’t want to write services twice for my external clients and internal clients.
  • Everything except our code runs in different thread.For example all the IO and DB related code runs in different thread. Our code always runs in single thread.
  • The above can be understood by an example of 2 concurrent requests. If there are no IO or other parallelizable requests Node will process requests one by one.But if there is an IO operation in first request ,Node will put that IO operation into another thread and takes the second from the event loop. This gives us a virtual feeling of requests/our code being executed in parallel. This is achieved by using 2 libraries called libev & libeio
  • Better for simple web site / ReST kind of service applications. ie Only if our code which is executing in the single thread completes as soon as possible. If we can route the long running process to another thread such as how IO, DB,Network related operations are performed, its fine.
  • Its production ready and so many big busiest business sites are using it. Check out NodeJS site for the list of big users.
  • Since it uses same language (javascript) the training cost is less and easy for the new developers or even designers who know js.
Ensuring that our code in Node.JS is not running in parallel
This is just a code snippet to prove that our code is not running in parallel in Node.JS. Main reason is Node.JS user code don’t have capability to create it’s own threads. Below is a code snippet which puts a delay of 5 seconds in a normal request. If you hit the URL (http://localhost:8000) from your browser you will see that the response is coming after 5 seconds.
var http=require('http')
http.createServer(function (req, res) {
    var startTime= new Date();
    console.log("Process started at :"+startTime.toString());
    
    res.writeHead(200, {'Content-Type': 'text/plain'});
    while(new Date().getSeconds() < startTime.getSeconds() + 5) {
        // I should have googled for a sleep method.
    }
    res.end('Start time:'+startTime.toLocaleTimeString()+",EndTime:"+new Date().toLocaleTimeString());
    }).listen(8000, "127.0.0.1");
    console.log("Server started @ 127.0.0.1:8000");

The response in browser will be.

Start time:08:46:21,EndTime:08:46:26

Now Open 2 tabs in your browser and hit the same url simultaneously. The result will be

Start time:08:47:21,EndTime:08:47:26

Start time:08:47:26,EndTime:08:47:31

It clearly says that the Node.JS is single threaded from our application point of view and it needs to wait to complete current user code to take another request.If my delay code was to fetch contents from file it should have processed differently as the I/O code will go into another thread.Think about ASP.Net.If you write the same code in ASP.Net and hit simultaneously from 2 browser tabs, the results would be

Start time:08:47:51,EndTime:08:47:56

Start time:08:47:52,EndTime:08:47:57

Ok. What about seeing the Node.JS code execution in parallel.I am altering the delay code to execute a sql query in SQL server. Query is nothing but a WAIT FOR DELAY statement.

var http=require('http')
var sql=require('node-sqlserver')
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write("Process started at :"+new Date().toString()+'<br/>');
    var conn_str = "Driver={SQL Server Native Client 10.0};Server=(local);Database=master;Uid=sa;Pwd=Password!"
    sql.open(conn_str, function (err, conn) { 
        if (err) { 
            res.end('Error in DB opening'+err.toString());
            return; 
        }
        conn.queryRaw("WAITFOR DELAY '000:00:10'", function (err, results) { 
            if (err) { 
                    res.end('Error in query execution' + err);
                    return; 
            }
            res.end('DB execution completed @'+new Date().toLocaleTimeString());
        }); 
        res.write('DB Execution (WAIT FOR DELAY "000:00:10") started @ '+new Date().toLocaleTimeString() +'<br/>');        
    }); 
}).listen(8000, "127.0.0.1");
console.log("Server started @ 127.0.0.1:8000");

If you are not familiar with how to setup SQL Server with NodeJS please refer the below link.
http://weblogs.asp.net/chanderdhall/archive/2012/06/19/microsoft-sql-server-driver-for-nodejs.aspx

After this I tried hitting the url from different browser tabs and I got the below output.

Process started at :Fri Jul 06 2012 20:45:51 GMT+0530 (India Standard Time)
DB Execution (WAIT FOR DELAY "000:00:10") started @ 20:45:51
DB execution completed @20:46:01


Process started at :Fri Jul 06 2012 20:45:53 GMT+0530 (India Standard Time)  
DB Execution (WAIT FOR DELAY "000:00:10") started @ 20:45:53
DB execution completed @20:46:03

Hope you understood the output. The second request was able to get into execution only because the first request entered into SQL execution which happens in different thread. For more details refer the below link.

http://www.quora.com/How-does-IO-concurrency-work-in-node-js-despite-the-whole-app-running-in-a-single-thread

The programming model

All the operations which are to be done after async calls like I/O calls needs to be inside the event handler / callbacks. in simple words nested callbacks. So lets see how to read a file after a sql database call where the file read is depend on the first sql execution result. 

var http=require('http')
var sql=require('node-sqlserver')
var fs=require('fs')
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write("Process started at :"+new Date().toString()+'<br/>');
    var conn_str = "Driver={SQL Server Native Client 10.0};Server=(local);Database=master;Uid=sa;Pwd=Password!"
    sql.open(conn_str, function (err, conn) { 
        if (err) throw err;
        conn.queryRaw("WAITFOR DELAY '000:00:10'", function (err, results) { 
            if (err) throw err;
            res.end('DB execution completed @'+new Date().toLocaleTimeString());
            fs.readFile('joy.txt', function (err, data) {
                if (err) throw err;
                console.log(data);
            });
        }); 
        res.write('DB Execution (WAIT FOR DELAY "000:00:10") started @ '+new Date().toLocaleTimeString() +'<br/>');        
    }); 
}).listen(8000, "127.0.0.1");
console.log("Server started @ 127.0.0.1:8000");

Simple isn’t it? Lets consider one more scenario where there is parallelism in SQL and File operations and another operation needs to be performed after these 2 operations.

But this needs an additional check to ensure that both the operations are completed.ie NodeJS don’t have native beautiful way of handling multiple async callbacks and do operations based on that.So inject our own logic.Keep 2 variables to hold the return state and in the post processing function check the variables. 

var http=require('http')
var sql=require('node-sqlserver')
var fs=require('fs')
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    var bSQLCompleted=false;
    var bFileCompleted=false;
    var conn_str = "Driver={SQL Server Native Client 10.0};Server=(local);Database=master;Uid=sa;Pwd=Password!"
    sql.open(conn_str, function (err, conn) { 
        if (err) throw err;
        conn.queryRaw("WAITFOR DELAY '000:00:05'", function (err, results) { 
            if (err) throw err;
            res.end('DB execution completed @'+new Date().toLocaleTimeString());
            bSQLCompleted=true;
            postSQLnFileReadOperation(bSQLCompleted,bFileCompleted);
        }); 
    }); 
    fs.readFile('joy.txt', function (err, data) {
        if (err) throw err;
        bFileCompleted =true;        
        postSQLnFileReadOperation(bSQLCompleted,bFileCompleted);
    });
}).listen(8000, "127.0.0.1");
console.log("Server started @ 127.0.0.1:8000");
//Accept the http variable if you want to do something specific to output
function postSQLnFileReadOperation(bSQL,bFile){
    if(bSQL && bFile) console.log("Operation after SQL & File read");
}


More links below.
http://raynos.github.com/presentation/shower/controlflow.htm
http://stevehanov.ca/blog/index.php?id=127
http://stackoverflow.com/questions/4234619/how-to-avoid-long-nesting-of-asynchronous-functions-in-node-js
http://stackoverflow.com/questions/5172244/idiomatic-way-to-wait-for-multiple-callbacks-in-node-js

Monday, July 12, 2010

Using Delegates for async method invocation

Problem

I want to call a method asynchronously in a synchronous environment. ie the subsequent lines should execute immediately after the method call regardless how much time the method takes to execute.

Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess")
TimeConsumingMethod()
Debug.WriteLine("After LongProcess")
End Sub
Private Sub TimeConsumingMethod()
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(2000)
Debug.WriteLine("Done!!!")
End Sub



When we execute the above code it will result as follows.


Before LongProcess

Done!!!

After LongProcess


But what I want is

Before LongProcess

After LongProcess

Done!!!


The immediate answer

If we ask this question to any developer the immediate answer will be “use threading”.Yes that is correct we can use threading.But is there an other easier solution?


Solution

I was in the category of saying “threading” until I heard about the async method invocation using delegates.Here goes the solution.



  • Create a delegate to match with your long running method signature.

  • Declare a delegate variable and instantiate it by passing the address of the long running method.

  • Call the BeginInvoke Method of the delegate which calls the pointed method in asynchronous fashion.



Public Delegate Sub MyAsyncDelegate()
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess")

Dim del As MyAsyncDelegate = New MyAsyncDelegate(AddressOf TimeConsumingMethod)
del.BeginInvoke(Nothing, Nothing)

Debug.WriteLine("After LongProcess")
End Sub
Private Sub TimeConsumingMethod()
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(20000)
Debug.WriteLine("Done!!!")
End Sub


Passing parameter

You can pass type safe parameters into this methods.For that just change the delegate signature.This automatically ask you to change the function which you are passing into delegate.



Public Delegate Function MyParamAsyncDelegate(ByVal data As String)

Private Function TimeConsumingMethod(ByVal data As String)
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(20000)
Debug.WriteLine("Done!!! Parameter =" & data)
End Function

Private Sub btnCallParam_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess with param")

Dim del As MyParamAsyncDelegate = New MyParamAsyncDelegate(AddressOf TimeConsumingMethod)
del.BeginInvoke(tbData.Text, Nothing, Nothing)

Debug.WriteLine("After LongProcess with param")
End Sub



Processing return values in async method invocation

When we execute a method we might be expecting some values back after the processing.Now lets see how to get the return value.First change the signature of the method such that it returns something.Obviously return the value.

Now comes a new delegate named AsyncCallback which points to the async delegate execution completed method.We need to pass this delegate variable to the InvokeAsync method of our delegate.

The completed method should accept one parameter of type IAsyncResult which is must when we point using AsyncCallback.The importance of this variable comes when we need the return value.

First we need to cast to AsyncResult which is the concrete implementation of IAsyncResult.Then get the AsyncDelegate property which is our delegate and call the EndInvoke method on that.Confused??The change is only in the completed method where we process the return value.See the below code to get clarified.



Public Delegate Function MyParamAsyncDelegate(ByVal data As String) As Integer

Private Function TimeConsumingMethod(ByVal data As String) As Integer
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(5000)
Debug.WriteLine("Done!!! Parameter =" & data)

'Return the length to read by completed method
Return data.Length
End Function

Private Sub btnCallBackParam_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess")
Dim delCallBack As MyParamAsyncDelegate = New MyParamAsyncDelegate(AddressOf TimeConsumingMethod)

Dim cb As AsyncCallback = New AsyncCallback(AddressOf TimeConsumingMethodCompleted)
Dim res As IAsyncResult = delCallBack.BeginInvoke(tbDataCallBack.Text, cb, Nothing)

Debug.WriteLine("After LongProcess")
End Sub

Private Sub TimeConsumingMethodCompleted(ByVal ar As System.IAsyncResult)
Dim asr As AsyncResult = DirectCast(ar, AsyncResult)
Dim del As MyParamAsyncDelegate = DirectCast(asr.AsyncDelegate, MyParamAsyncDelegate)
Dim result As Integer = del.EndInvoke(ar)
Debug.WriteLine("Async operation completed method.length of the string :" & result.ToString)
End Sub



Uploaded a sample here