Lambda and Functional Programming

After I started looking at the core of functional programming here, more and more question followed their ways into my head. It’s pretty common now a days to face new and newer piece of reusable code components on a daily basis. They redefine how things ought to be done. I’m not complaining at all, it is indeed intriguing to see them come forward so fast. And the fun part is all of them follows the principles laid out years ago. Functional programming is no different.

Greek alphabet of coolness, 位

The reason the first word in the title of the blog is lambda because the character is聽 is almost synonymous with anonymous methods/functions, almost all the programming language around has the capabilities to create some form of support of constructing lambdas that contain a unit of work. Greek people made even their alphabets cooler than anyone else. And when I started thinking of actually learning a functional language, my first question was why would I need a language that enforces immutability? Can’t I myself keep immutability intact and yet code with the same principles in any other imperial programming language? The answer is yes, sure I can. The point lies somewhere else. Functional Programming is not something really new. It is not something refactored out of imperial programming. In fact, the tale is as old as general/state driven computing as we know it.

Turing and his states

The moment you start talking about computing, you will start living in Alan Turing‘s head. Whatever we build today, whatever we are doing is still following the principles of his infamous computational model Turing Machine. This was his work in 1936 and we still can’t imagine anything out of it. Amazing, isn’t it? A simple tape drive driven machine model is empowering every possible machine you see now. He is indeed the puppet master of computing.

If we look around carefully, everything around is state driven. Object Oriented programming is state driven. Every instance we write of a class is state driven. When you use a cool framework like redux to maintain your application state, you are doing nothing except following the same principles of a basic state machine, especially a DFA. I can’t emphasize this enough, Turing is synonymous to computation.

Now we get into the head of someone else. Someone else named Alonzo Church. Alonzo Church was building a computational model at the same time Turing was working on his own. His computational model was mathematical function driven where every function is a black box, takes an input and drives out an output. Functions can be sent as inputs and every logical relation is based on a simple domain to range mapping. Sounds familiar? Yes, his work was the father of Functional Programming published in the same year, 1936. Alonzo’s model was based off his work on聽Lambda Calculus. Fret not, the name is scary, the actual thing is way simpler than it sounds, I think it sounds way cooler because the damn name has lambda on it.

The last but not the least amazing part is, Turing didn’t know any of these. And Alonzo was his doctoral advisor. 馃槈 The whole hypothesis is named after both of them since Turing proved that Alonzo’s model is equivalent of his computational model. And thus Church-Turing Thesis was born.

What is Lambda Calculus?

We are going to take a very very quick tour of lambda calculus. It doesn’t have any traditional calculus-esque constructs in it. There are multiple variants of it. We will only take a quick tour of pure lambda calculus. Just enough to know how functional programming is devised so we can think alike.

The syntax is simple, in context free grammar:

expr ::= constant| variable | (expr expr)聽| 聽(位 .variable expr )

If you are not used to context free grammar, this construct tells how a lambda calculus expression is written. It says an expression can be a constant, a variable, a set of expressions and at the very end, the abstract form of lambda calculus that states a definition of a function like:

位x. e

Here, the聽x is the input parameter and聽 e is the expression. The input parameter is聽bound in that expression聽e.聽And the abstract form of lambda calculus defines a function. Remember this is the definition, it can be invoked and used with real arguments. If this is get all confusing for you, let’s jump into an example. Let’s say we want to define a function that adds 1 to a variable X.

From my perspective we are building a blackbox function that takes one input and converts it to a output.

BasicFunction

Now, to express it as a聽lambda calculus abstract聽we will use the character聽to define the function,聽x as the input parameter and the output will be聽x+1. So this will end up in the expression body聽e. So, it looks like

位x. x+1

We have our first lambda abstract! yay! This is the function definition. To invoke it, let’s say, we want to use 5 as an input argument. The invocation will look like

(位x. x+1) 5

If this is getting confusing again, remember, we don’t have a name for our function here. The definition itself is the name and the body. And the input parameter as聽x is 5 now. To deduce the next line, we replace聽x by 5 and we take the聽位x off.聽

(位x. x+1) 5
5 + 1
6

This is a very basic sample of beta reduction. Remember聽lambda calculus only have inputs, expression and the output. It is indeed that simple.

Now, back to programming world. Remember Javascript’s infamous self invoking method?

(function (x) {
    return x + 1;
})(x);

I hope now you see where the principles come from. Amazing. Isn’t it?

The notion of recursion

We are taking a pretty big jump here. Ever wondered how recursions work? We invoke the same method inside of it and we end up in the same place over and over again. Can聽lambda calculus define recursion?

It can. Lets assume that we have a function聽位x. x x. And we invoke it with itself as a parameter. So, it looks like:

(位x. x x)聽(位x. x x)
(位x. (位x. x x) (位x. x x))聽(位x. x x) 聽 聽聽
// replacing x x with the (位x. x x) itself
(位x. x x)聽(位x. x x) 聽 聽// 聽by the same rule of beta reduction, we take of the聽notation and the input

We applied beta reduction here but we still ended up in the same place we started. This is called聽Omega Combinator which is聽a聽divergent combinator since it has no normal form.聽If you apply beta reduction on it, you will end up in the same construct again. This is basically a simple mathematical model for an infinite loop…pointing to a recursion.

A combinator in a lambda calculus is defined by an lambda expression that has no free variables. What is a free variable you ask? Looks like you want a nice course on Lambda Calculus. 馃檪

I found these very helpful if they are read or viewed in order:

  1. Crash Course on Lambda Calculus by Ayaka Nonaka聽
  2. Lambda Calculus – Computerphile
  3. Lambda Calculus by Jim Grandpre
  4. Y combinator function. What is it?

If you read/viewed all these already, you probably know this already. The lambda calculus way to self reference a function inside itself is called the聽Y Combinator. Yeah, mind blown, isn’t it?

Computation is not really far from philosophy or history. It also starts from the聽alpha and ends in聽omega. I stay clear of religion but had to mention this. (It sounded cool in my head, doh!)

So, next time you write a lambda to look cool on your codebase or while you are talking to people about the nifty map, reduce and various unit of work methods, pay a little homage to Church and Turing. What they said years ago makes you look cool now.

Advertisements

Going functional: the journey begins!

For a long time, I really didn’t get to treat this blog as my own blog. I mean, sure, I said things I’m enthusiastic about. But I think the purpose of having a blog is not about catching attention rather having a safe place where you can have a dialogue with your mind.

I recently started dabbling with functional programming. I don’t know why though. For long I heard a lot over it from the constant stream of social networks. I never managed to find a reason why should I ever care about this. I think secretly I was afraid if I ever take this up, I might succumb to my curiosity and finally spend time learning things I really don’t need right now. Then again, knowledge never fails.

So, here I am. After spending around 8 or 9 hours of active reading, I barely made a scratch in the surface of it. But it’s a start. My major breakthrough was to be able to get back to that mindset where I could just play with something when I have the least knowledge backing it. It’s a scary game but boy is this fun to play.

 

Ahoy! functional programming!

The first and foremost notion of functional programming I got from watching people talk about it is that it probably has something to do with ‘functions’ being the first citizen in a programming language. And immutability plays a big part. That lead me to the same place where I started learning programming. 聽I mean I knew “what” was I learning, I did not know “why” I was learning that. I didn’t have the guts to ask because I didn’t know anything about the context. Now, I stand in a corner where I get to ask the question. Why?

 

Why functional programming is like this?

Surprisingly functional programming didn’t spawn from the concept of programming construct “function” being the first class citizen in a programming language. The fun thing is the word ‘functional’ in the very title doesn’t even point to programming functions. It actually points to mathematical functions. Before I go into that, please allow me to tell yourself to ‘unlearn’ programming as you know it. Especially if you are a person like me who knows imperative programming only. 聽The reason to unlearn what you know is to give you a clean fresh slate to work with. I know that is easier said than done. But as long as you know it and open to see things, you’d be fine!

So, let’s dive in. Let’s assume a simple, very simple mathematical function like the following:

let add1 x = x + 1

For reference I’m using F# here. The two programming languages I want to at least try out is F# and Scala. There’s a solid debate on Scala not being a total functional programming language. But, that is a story for another day. My goal is to understand Apache Spark better in the process too and Scala is just too friendly with it. In the process I’m trying to kill two birds with one bullet. This blog will roughly use F# for reference but nothing here is not understandable even if you haven’t seen F# in your life.

If we have a look at the function here we will see that we are adding 1 to another number here. Any programming language in existence is capable of doing that. What is the difference here except the syntax? This is where I send you back to the “unlearn” step. Let’s see how this is interpreted inside. The F# interpreter will read the function signature like the following:

val add1 : x:int -> int

the聽 val add1 part is self explanatory, we don’t want to worry about that part right now. What about the next part聽x:int -> int. This is where my聽imperative programming brain聽came into work and devised a misleading explanation. And it sounded something like :

The聽x:int -> int聽stands for a method signature that takes an input parameter聽x of type聽int and it returns another聽int.

Like I said, this is wrong but it felt legit when I devised it in my brain. The more I delved into it, the more I realized the wrongs in my ways. Years of imperative programming have assembled my neurons to reinforce these concepts as the general means of programming. Since functional programming resorts to mathematical functions, why can’t we see it from that specific aspect?

A mathematical function takes a set of values that are used as聽inputs into the聽function domain聽and the聽function maps it to a set of possible聽outputs. The set of the outputs are called聽range. All the functions do here is聽map the inputs to the聽outputs.

To visualize:

Functions_Add1

I’m not sure whether I have explained enough how my brain was convinced that it is different. To reinforce that the biggest difference here to look for is the process of doing things. We are聽transforming the聽inputs here. Not necessarily returning a value.聽Mathematical functions transforms inputs, they don’t produce聽any聽 side effect to the聽inputs. What I want to mean is if you add 5 and 1 you will get back 6. The input parameter 5 will not have any possible side effect on it. And a聽mathematical function always gives the聽same output for a specific given聽input. My聽imperative programming brain got it almost right. The right explanation for 聽x:int -> int is an int domain to int range mapping.

The function聽add1 maps an int input domain to an int range. And for the fact that mathematical functions DO NOT implicate any side effects, it was implicitly important聽to have聽immutability embedded inside them. Because if your programming function generates a state or a side effect then it will 聽not comply with mathematical functions. So the implementation layer will fail to comply with the theoretical counterpart. And that is why聽immutability聽is vital in functional programming.

 

I still don’t see the difference

This is really nice and all. But from my聽imperative programmer brain’s perspective, is it really that different? If I didn’t take this journey to figure out why functional programming is like this, won’t I be able to write anything in any possible functional programming language? And yes, for sure my brain will be able to. But here is the fun part. What our brain learns implicitly is really hard to explain using the same brain. Otherwise, machine learning will be a piece of cake. My point was to actually try to “know” it, not get habituated to it. Thus when I encounter a problem I can deduce a solution through what I know rather than just plugging constructs I have seen.

Still, I need an answer. Where is the difference? I still see inputs and outputs. Nothing else. My聽imperative programmer brain is quite right here, we聽assign a value to a聽variable and the聽function returns a聽result.聽

Now, wait a minute and lets see a bit into the word聽variable and聽assign. The word聽variable and聽assign points to the fact where we use the聽variable as a placeholder for the actual聽value聽. And the concept of聽assigning a聽value to a variable points to the concept of storing something in that placeholder. Is it the same here? No. Mathematical methods don’t imply placeholders. It creates a mapping and generalizes that mapping. So saying聽add1 5 is not assigning聽5 to x. It is actually聽binding 5 to聽x. The process of binding is not reusing聽add1.聽add1 5 is pointing to a method binding that says when聽I’m invoked you will end up in the range.聽 It looks really the same but it is not. Think of basically doing a string replace where the x is replaced with 5.

Hopefully now you will see more reasons reinforcing聽immutability.聽And thus the function name, 聽add1聽is not a reusable construct for the function. It’s just a shortcut expression for the聽range it returns. We are replacing a聽function value, not the聽function!

To sum it up the generic function value signature is聽

val functionName : domain -> range

So, here’s a trick question. How do we define constants then? The answer is writing a function where the range is just the value from any possible domain. 馃檪

The motivation behind starting to write again while I learn something goes straight to Chris Smith. He wrote Programming F#聽and his MSDN blog while he was writing F# is found here. They are highly entertaining and please don’t refrain yourself from looking into them.聽According to him it is one of the best ways to learn a language and I kind of agree with him despite the fact I lost the courage or interest to do that regularly before.

I also found Learn X in Y Minutes聽very very fun to have a blind date with a number of programming languages. If I ever get to talk about Scala (that depends on me having time to learn it), I will definitely talk more about this website.

The resources for this blog are taken from:

  1. F# for fun and profit
  2. Learn X in Y Minutes

Hope this was entertaining albeit it comprises of boring details! I intend to write a dummies note onthe church-turing hypothesis which essentially blossomed into lambda calculus. Functional Programming is almost directly derived from it. But, it all depends on how much time I will possibly have to cover that. Until then, see ya.

Confessions

Before I start writing this, I must say this is probably the first time I’m treating this blog like I want it to be treated. Most of the time I wrote things people only cares about when they want their problem fixed. For the last couple of months or a year I didn’t even write much. It seems that socials has taken a big chunk of my time and now I’m trying to get out of that addiction.

Money, papers with vengeance

Around 4 years ago, I gave into the concept of working for money. Money talks, doesn’t it? It talks louder than anything else. So, that was it for me. I went out with a little help of someone I know, went into an interview, practically said I would do anything to get some money and started working.

I started working on perl. It’s a nice little language (believe me, it took a long time for me to come to this verdict). Nice and amusing as it is, it was indeed mischievous. For a guy who doesn’t know much about linux or any unix per say, it was a hard time to cope up and get going. Boy, I hated it in the beginning. I used to mail my superior almost everyday to make sure that someday he ports me somewhere I can write something C#.

The fact I liked Windows so much wasn’t a fun party either. The internet is right now is full of sages. Sages who are so opinionated about everything so that unless you don’t come in terms with what they believe, they’d literally treat that act as a blasphemy. Boy, I even had a facebook page dedicated for trolling me and one of my very close mentors. Fun times, I still don’t know who was behind that. Wish I knew. But that’s another story for another day.

Present is a gift, a confusing gift indeed

Right at this point of my life, I’m probably the most confused as ever. When I was a kid, i saw my mom and dad work, work like hell. Just trying their best to put everything in place and make the ends meet. And the worst part of this is now I understand the necessity of it. I really didn’t at that time. Now I don’t have an excuse for being this person. Now, I don’t know what I am supposed to be.

It’s really funny. When I was a preteen or a teen all I ever wanted to become is a musician. That is of course before life came in and hit me in the nuts. That is when your dreams go down the drain and you start doing the thing you’re good at and the one that makes money. I was no different at all. I’m lucky that I’m passionate about it. Otherwise I don’t know what would happen.

Know thyself

When you start to understand who you are, two things will happen. You’d know your limits, you’d be a good friend to yourself. The worst part of all of this is, it would make you aware of everything. It would take away the spontaneous sets of emotions since now you can pretty much predict what your brain would do.

聽Love and its baggage

Boy, this shit confused me more than anything else ever did in my life. I lost and gained a lot through love. For me I think it had to do a lot with finding your own purpose. When one person becomes a lot more important than any goal you ever chased, when that very person becomes your prime directive. And your brain goes to a hyperdrive. It starts to calculate all possible memories you could make with her. Its a tree your brain loves to parse. But beware, it also comes with attachments. For me it was even scarier, my childhood was insanely lonely and I basically grabbed anyone I saw that I imagined can play a part in my life. Scary, huh? Well you haven’t heard the scariest part yet. The moment you drop your guards all the insecurities will show their ugly heads. A person you want you around would see you as you truly are. That is sometimes perceived wrong on the other side. At some point you’d get scared to open up. Because you don’t know what it will cost you. It would only make you feel no one wants to be around you just because it is you. And that thought itself would isolate you from the rest of the world just like that.

To obligations and beyond

Obligations are the shittiest thing you’d ever encounter. They’d make you pay, I tell you. You look at your family, you see obligations. You look at the person you love most, you feel a drive to make things better for her. Fuck me, I can’t find anyone with a pair of eyes I don’t have to pay anything. I don’t owe anything. For hell as I sure,I don’t owe anything to this world. I dont. People talk about priorities. Trust me priority is a two way street. It only meets when both of them starts to work towards each other. Much like a bidirectional a star search.

Freedom from life itself

Rules never worked on me. Probably never will. My brain is a child with always asking “Why”. And I hate the fact that it does that. Not that it helps it anyway , it still does that. Youd think Kurt Cobain was wrong. I don’t see it that way. I don’t know why I have a twisted sense of judgement. The pursuit of happiness is said to be started when you leave your expectations behind. What if I expect to find something that will unbind me from expectations?

Paradox indeed.

I thought I knew C# : Garbage collection & disposal. Part-II

Okay, we are back in to collect “garbage” properly. If you haven’t the first part of this post you might want to read it here. We are following norms and conventions from the first post here too.

聽Starting things from where we left off:

This write up continues after the first one where we ended things with SafeHandle class and聽IDisposable聽聽interface. I do see how intriguing this is of course. But before that, like a unexpected, miserable commercial break before the actual stuff comes on your TV, let’s go have a look on something called finalization.

What you create, you “might” need to destroy:

If you know a little bit of C++ you’d know that there is a thing called聽destructor and the name implies it does the exactly opposite of what a constructor does. C++ kind of needs it since it doesn’t really have a proper garbage collection paradigm. But that also raises the question of whether C# has a destructor聽and if it does what does it do and why do we even have one since we said managed resourced would be collected automatically.

Lets jump onto some code, shall we?

class Cat
{
    ~Cart()
    {
        // cleanup things
    }
}

Wait a minute, now this is getting confusing. I have聽IDisposable::Dispose() and I have a destructor. Both looks like to have same responsibility. Not exactly. Before we confuse ourselves more, lets dig a bit more in the code. To be honest, C# doesn’t really have a destructor, it’s basically a syntactic sugar and inside c sharp compiler translates this segment as

protected override void Finalize()
{
    try
    {
        // Clean things here
    }
    finally
    {
        base.Finalize();
    }
}

We can pick up to things here. First thing is the destructor essentially translates to a overridden聽Finalize() method. And it also calls the聽Finalize()base class in the finally block. So, it’s essentially a recursive聽finalize().Wait, we have no clue what is聽Finalize().

Finalize, who art thou?

Finalize is somebody who is blessed to talk with the garbage collector. If you have already questioning where the topics we discussed in last post comes in help, this is the segment. Lets start getting answers for all our confusions on last segment. First, why聽Finalizeis overridden and where does it gets its signature.聽Finalize gets its signature from Object class. Okay, understandable. What would be the default implementation then? Well, it doesn’t have a default implementation. You might ask why. A little secret to slip in here, remember the聽mark聽step of garbage collector. He聽marks a type instance for finalization if and only if it has overridden the聽Finalize() method. It’s your way of telling the garbage collector that you need to do some more work before you can reclaim my memory. Garbage collector would聽mark this guy and put him in a聽finalization queue which is essentially a list of objects whose finalization codes must be run before GC can reclaim their memory. So, you are possibly left with one more confusion now. And that is, you understood garbage collector uses this method to聽finalize things, i.e. doing the necessary cleanup. Now, then why do we need聽IDisposable where we can just override finalize and be done with it, right?

Dispose, you confusing scum!

Turns out dispose intends to point out a pattern in code that you can use to release unmanaged memory. What I didn’t tell you about garbage collectorbefore is you don’t really know when he would essentially do that, you practically have no clue. That also means if you write an app that uses unmanaged resources like crazy like reading 50-60 files at a time, you are using a lot of scarce resources at the same time. And in the end you are waiting for GC to do his job but that guy has no time table. So, hoarding these resources is not a good idea in the meantime. Since releasing unmanaged resources are developers duty, putting that over a finalize method 聽and waiting for GC to come and invoke that is a stupid way to go. Moreover, if you send an instance to a finalization queue, it means, GC will essentially do the memory cleanup in the next round, he will only invoke finalize this round. That also means GC has to visit you twice to clear off your unused occupied memory which you kinda need now. And the fact that you might want to release the resources NOW is a pretty good reason itself to not wait for GC to do your dirty work. And, when you actually shut down your application, Mr. GC visits you unconditionally and takes out EVERYONE he finds. I hope the need of聽Dispose()聽is getting partially clear to you now. We need a method SomeMethod()聽that we can call which would clean up the unmanaged resources. If we fail to call that at some point, just to make sure garbage collector can call that we will use that same method inside聽Finalize() so it is called anyhow. If I have not made a fool out of myself at this point, you have figured out the fact that聽SomeMethod() is聽Dispose(). Okay, so we know what we are going to do. Now we need to act on it. We will implement the dispose pattern we have been talking about. The first thing we would do here is we would try to write code that reads a couple of lines from a file. We would try to do it the unmanaged way, then move it to slowly to the managed way and in the process we would see how we can use IDisposable there too.

Doing things the unsafe way:

I stole some code from a very old msdn doc which describes a FileReader class like the following:

using System;
using System.Runtime.InteropServices;
public class FileReader
{
    const uint GENERIC_READ = 0x80000000;
    const uint OPEN_EXISTING = 3;
    IntPtr handle;
[DllImport("kernel32", SetLastError = true)]
    static extern unsafe IntPtr CreateFile(
            string FileName,                    // file name
            uint DesiredAccess,                 // access mode
            uint ShareMode,                     // share mode
            uint SecurityAttributes,            // Security Attributes
            uint CreationDisposition,           // how to create
            uint FlagsAndAttributes,            // file attributes
            int hTemplateFile                   // handle to template file
            );
[DllImport("kernel32", SetLastError = true)]
    static extern unsafe bool ReadFile(
            IntPtr hFile,                       // handle to file
            void* pBuffer,                      // data buffer
            int NumberOfBytesToRead,            // number of bytes to read
            int* pNumberOfBytesRead,            // number of bytes read
            int Overlapped                      // overlapped buffer
            );
[DllImport("kernel32", SetLastError = true)]
    static extern unsafe bool CloseHandle(
            IntPtr hObject   // handle to object
            );
    public bool Open(string FileName)
    {
        // open the existing file for reading
        handle = CreateFile(
                FileName,
                GENERIC_READ,
                0,
                0,
                OPEN_EXISTING,
                0,
                0);
if (handle != IntPtr.Zero)
            return true;
        else
            return false;
    }
    public unsafe int Read(byte[] buffer, int index, int count)
    {
        int n = 0;
        fixed (byte* p = buffer)
        {
            if (!ReadFile(handle, p + index, count, &n, 0))
                return 0;
        }
        return n;
    }
    public bool Close()
    {
        // close file handle
        return CloseHandle(handle);
    }
}

Please remember you need to check your聽Allow Unsafe Code checkbox in your build properties before you start using this class. Lets have a quick run on the code pasted here. I don’t intend to tell everything in details here because that is not the scope of this article. But we will build up on it, so we need to know a little bit. The聽DllImport attribute here is essentially something 聽you would need to use an external dll (thus unmanaged) and map the functions inside it to your own managed class. You can also see that’s why we have used the聽extern keyword here. The implementations of these methods doesn’t live in your code and thus your garbage collector can’t take responsibility of clean up here. 馃檪 The next thing you would notice is the聽fixed聽statement. fixed statement essentially link up a managed type to an unsafe one and thus make sure GC doesn’t move the managed type when it collects. So, the managed one stays in one place and points to the unmanaged resource perfectly. So, what are we waiting for? Lets read a file.

static int Main(string[] args)
{
    if (args.Length != 1)
    {
        Console.WriteLine("Usage : ReadFile <FileName>");
        return 1;
    }
    if (!System.IO.File.Exists(args[0]))
    {
        Console.WriteLine("File " + args[0] + " not found.");
        return 1;
    }
    byte[] buffer = new byte[128];
    FileReader fr = new FileReader();
    if (fr.Open(args[0]))
    {
        // Assume that an ASCII file is being read
        ASCIIEncoding Encoding = new ASCIIEncoding();
        int bytesRead;
        do
        {
            bytesRead = fr.Read(buffer, 0, buffer.Length);
            string content = Encoding.GetString(buffer, 0, bytesRead);
            Console.Write("{0}", content);
        }
        while (bytesRead > 0);
        fr.Close();
        return 0;
    }
    else
    {
        Console.WriteLine("Failed to open requested file");
        return 1;
    }
}

So, this is essentially a very basic console app and looks somewhat okay. I have created a byte array of size 128 which I would use as a buffer when I read. FileReader returns 0 when it can’t read anymore. Don’t get confused seeing this.

while (bytesRead > 0)

It’s all nice and dandy to be honest. And it works too. Invoke the application (in this case the name here is 聽TestFileReading.exe) like the following:

TestFileReading.exe somefile.txt

And it works like a charm. But what I did here is we closed the file after use. What if something happens in the middle, something like the file not being available. Or I throw an exception in the middle. What will happen is the file would not be closed up until my process is not closed. And the GC will not take care of it because it doesn’t have anything in the聽Finalize() method.

Making it safe:

public class FileReader: IDisposable
{
    const uint GENERIC_READ = 0x80000000;
    const uint OPEN_EXISTING = 3;
    IntPtr handle = IntPtr.Zero;
    [DllImport("kernel32", SetLastError = true)]
    static extern unsafe IntPtr CreateFile(
            string FileName,                 // file name
            uint DesiredAccess,             // access mode
            uint ShareMode,                // share mode
            uint SecurityAttributes,      // Security Attributes
            uint CreationDisposition,    // how to create
            uint FlagsAndAttributes,    // file attributes
            int hTemplateFile          // handle to template file
            );
    [DllImport("kernel32", SetLastError = true)]
    static extern unsafe bool ReadFile(
            IntPtr hFile,                   // handle to file
            void* pBuffer,                 // data buffer
            int NumberOfBytesToRead,      // number of bytes to read
            int* pNumberOfBytesRead,     // number of bytes read
            int Overlapped              // overlapped buffer
            );
    [DllImport("kernel32", SetLastError = true)]
    static extern unsafe bool CloseHandle(
            IntPtr hObject   // handle to object
            );
    public bool Open(string FileName)
    {
        // open the existing file for reading
        handle = CreateFile(
                FileName,
                GENERIC_READ,
                0,
                0,
                OPEN_EXISTING,
                0,
                0);
        if (handle != IntPtr.Zero)
            return true;
        else
            return false;
    }
    public unsafe int Read(byte[] buffer, int index, int count)
    {
        int n = 0;
        fixed (byte* p = buffer)
        {
            if (!ReadFile(handle, p + index, count, &n, 0))
                return 0;
        }
        return n;
    }
    public bool Close()
    {
        // close file handle
        return CloseHandle(handle);
    }
    public void Dispose()
    {
        if (handle != IntPtr.Zero)
            Close();
    }
}

Now, in our way towards making things safe, we implemented聽IDisposable聽here. That exposed聽Dispose() and the first thing I did here is we checked whether the handle is IntPtr.Zero and if it’s not we invoked聽Close(). Dispose() is written this way because it should be invokable in any possible time and it shouldn’t throw any exception if it is invoked multiple times. But is it the solution we want? Look closely. We wanted to have a聽Finalize() implementation that will essentially do the same things if somehow聽Dispose()聽is not called. Right?

Enter the Dispose(bool) overload. We want the parameter less聽Dispose() to be used by only the external consumers. We would issue a second聽Dispose(bool) overload where the boolean parameter indicates whether the method call comes from a聽Dispose method or from the finalizer. It would be true if it is invoked from the parameter less聽Dispose() method.

With that in mind our code would eventually be this:

    public class FileReader: IDisposable
    {
        const uint GENERIC_READ = 0x80000000;
        const uint OPEN_EXISTING = 3;
        IntPtr handle = IntPtr.Zero;
        private bool isDisposed;

        SafeHandle safeHandle = new SafeFileHandle(IntPtr.Zero, true);

        [DllImport("kernel32", SetLastError = true)]
        static extern unsafe IntPtr CreateFile(
              string FileName,                  // file name
              uint DesiredAccess,              // access mode
              uint ShareMode,                 // share mode
              uint SecurityAttributes,       // Security Attributes
              uint CreationDisposition,     // how to create
              uint FlagsAndAttributes,     // file attributes
              int hTemplateFile           // handle to template file
              );

        [DllImport("kernel32", SetLastError = true)]
        static extern unsafe bool ReadFile(
             IntPtr hFile,                // handle to file
             void* pBuffer,              // data buffer
             int NumberOfBytesToRead,   // number of bytes to read
             int* pNumberOfBytesRead,  // number of bytes read
             int Overlapped           // overlapped buffer
             );

        [DllImport("kernel32", SetLastError = true)]
        static extern unsafe bool CloseHandle(
              IntPtr hObject   // handle to object
              );

        public bool Open(string FileName)
        {
            // open the existing file for reading
            handle = CreateFile(
                  FileName,
                  GENERIC_READ,
                  0,
                  0,
                  OPEN_EXISTING,
                  0,
                  0);

            if (handle != IntPtr.Zero)
                return true;
            else
                return false;
        }

        public unsafe int Read(byte[] buffer, int index, int count)
        {
            int n = 0;
            fixed (byte* p = buffer)
            {
                if (!ReadFile(handle, p + index, count, &n, 0))
                    return 0;
            }
            return n;
        }

        public bool Close()
        {
            // close file handle
            return CloseHandle(handle);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool isDisposing)
        {
            if (isDisposed)
                return;

            if (isDisposing)
            {
                safeHandle.Dispose();
            }

            if (handle != IntPtr.Zero)
                Close();

            isDisposed = true;
        }
    }

Now if you focus on the changes we made here is introducing the following method:

protected virtual void Dispose(bool isDisposing)

Now, this method envisions what we discussed a moment earlier. You can invoke it multiple times without any issue. There are two prominent block here.

  • The conditional block is supposed to free managed resources (Read invoking Dispose() methods of other IDisposable member/properties inside the class, if we have any.)
  • The non-conditional block frees the unmanaged resources.

You might ask why the conditional block tries to dispose managed resources. The GC takes care of that anyway right? Yes, you’re right. Since garbage collector is going to take care of the managed resources anyway, we are making sure the managed resources are disposed on demand if only someone calls the parameter less Dispose().聽

Are we forgetting something again? Remember, you have unmanaged resources and if somehow the Dispose() is not invoked you still have to make sure this is finalized by the garbage collector. Let’s write up a one line destructor here.

 ~FileReader()
 {
    Dispose(false);
 }

It’s pretty straightforward and it complies with everything we said before. Kudos! We are done with FileReader.

Words of Experience:

Although we are safe already. We indeed forgot one thing.聽If we invoke聽Dispose() now it will dispose unmanaged and managed resources both. That also means when the garbage collector will come to collect he will see there is a destructor ergo there is a Finalize() override here. So, he would still put this instance into Finalization Queue. That kind of hurts our purpose. Because we wanted to release memory as soon as possible. If the garbage collector has to come back again, that doesn’t really make much sense. So, we would like to suppress the garbage collector to invoke Finalize() if we know we have disposed it ourselves. And a single line modification to the Dispose() method would allow you to do so.

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

We added the following statement to make sure if we have done disposing ourselves the garbage collector would not invoke聽Finalize() anymore.

GC.SuppressFinalize(this);

Now, please keep in mind that you shouldn’t write a GC.SupperssFinalize() in a derived class since your dispose method would be overridden and you would follow the same pattern and call聽base.Dispose(isDisposing) in the following way:

class DerivedReader : FileReader
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;

      // Call the base class implementation.
      base.Dispose(disposing);
   }

   ~DerivedClass()
   {
      Dispose(false);
   }
}

It should be fairly clear to now why we are doing it this way. We want disposal to go recursively to base class. So, when we dispose the derived class resources, the base class disposes its own resources too.

To use or not to use a Finalizer:

We are almost done, really, we are. This is a section where Im supposed to tell you why you really shouldn’t use unmanaged resources whenever you need. It’s always a good idea not to write a Finalizer if you really really don’t need it. Currently we need it because you are using a unsafe file handle and we need to close it manually. To keep destructor free and as managed as possible, we should always wrap our handles in SafeHandle class and dispose the SafeHandle as a managed resource. Thus, eliminating the need for cleaning unmanaged resources and the overloaded聽Finalize() . You will find more about that here.

“Using” it right:

Before you figure out why I quoted the word聽using here, let’s finally wrap our work up. We have made our FileReader class disposable and we would like to invoke dispose() after we are done using it. We would opt for a try-catch-finally block to do it and will dispose the resources in the聽finally block.

FileReader fr = new FileReader();
try
{
    if (fr.Open(args[0]))
    {
        // Assume that an ASCII file is being read
        ASCIIEncoding Encoding = new ASCIIEncoding();
        int bytesRead;
        do
        {
            bytesRead = fr.Read(buffer, 0, buffer.Length);
            string content = Encoding.GetString(buffer, 0, bytesRead);
            Console.Write("{0}", content);
        }
        while (bytesRead > 0);
        return 0;
    }
    else
    {
        Console.WriteLine("Failed to open requested file");
        return 1;
    }
}
finally
{
    if (fr != null)
        fr.Dispose();
}

The only difference you see here that we don’t explicitly call Close() anymore. Because that is already handled when we are disposing the FileReader instance.

Good thing for you is that C# has essentially made things even easier than this. Remember the using statements we used in Part-I? An聽using statement is basically a syntactic sugar placed on a try-finally block with a call to Dispose() in the finally block just like we wrote it here. Now, with that in mind, our code-block will change to:

using (FileReader fr = new FileReader())
{
    if (fr.Open(args[0]))
    {
        // Assume that an ASCII file is being read
        ASCIIEncoding Encoding = new ASCIIEncoding();
        int bytesRead;
        do
        {
            bytesRead = fr.Read(buffer, 0, buffer.Length);
            string content = Encoding.GetString(buffer, 0, bytesRead);
            Console.Write("{0}", content);
        }
        while (bytesRead > 0);
        return 0;
    }
    else
    {
        Console.WriteLine("Failed to open requested file");
        return 1;
    }
}

Now you can go back to part-I and try to understand the first bits of code we saw. I hope it would make a bit better sense to you now. Hope you like it. Hopefully, if there’s a next part, I would talk about garbage collection algorithms.

You can find the code sample over github here.

I thought I knew C# : Garbage collection & disposal. Part-I

Yeah, that’s right, time to be a garbage guy. And if this line didn’t make you laugh, you probably know how bad of a stand up comedian I ever would make.

How things goes when anyone asks about these:

Now this is going to be long. And I’m going to jump into what I want to talk about right away. Let’s start with a regular Joe who writes C#. Let’s tell him to write a “safe” looking block of code that would essentially open a gzip file, read it as byte array, decompress the byte array聽using a buffer, write it over a memory stream and return it when he is done doing the whole thing.

This is something you might expect in return. This would be the block where the aforementioned byte array gets decompressed:

    public class Solution
    {
        public static byte[] Decompress(byte[] gzip)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
            {
                const int size = 4096;
                byte[] buffer = new byte[size];
                using (MemoryStream writeStream = new MemoryStream())
                {
                    int count = 0;
                    do
                    {
                        count = gzipStream.Read(buffer, 0, count);
                        if (count > 0)
                        {
                            memoryStream.Write(buffer, 0, count);
                        }
                    } while (count > 0);
                    return writeStream.ToArray();
                }
            }
        }
    }

And this would be a possible segment where you see the file being read:

    class Program
    {
        const int _max = 200000;
        static void Main()
        {
            byte[] array = File.ReadAllBytes("Capture.7z");
            Solution.Decompress(array);
        }
    }

And yes, the code sample credit goes to dotnetperls聽. The reason I started with an example before any explanations is I want to build up on this. I believe when you have a place to go, sometimes the fact that you know where you would end up reinforces what you will learn in the process. But it is very important here to know why you would end up here.

Breaking the code bits:

Let’s start breaking the code up into bits. Now, the first question you would ask the regular Joe like me is how do you claim this code block is “safe” and what do you mean when you say this is “safe”. The first answer would essentially be that there is a beautiful using block there which would essentially聽dispose the聽resources聽when it is done being used.

I focused three words here, throughout this articles I would bold out words like this and whenever I do that, if you don’t know exactly what I’m talking about, put these words in a dictionary in your brain and in turns I will explain all these. That also means if you think you know all of these, your journey ends here.

Words of wisdom:

The first word of wisdom here is聽dispose. And I would essentially start with some basics for it. Before going into dispose, we need to dive back on some proper backgrounds on .net garbage collection process. If you are totally new to this, garbage collector is an automatic memory manager, it lets you develop your application without having the need to free the memory every time. If I drove you inside more confusion, that means you need to know what happens when you聽allocate some memory, essentially which happens every time you declare and initiate any value or reference you write when you are writing C#.

Every time you write the new keyword聽to initialize an object in C#, you essentially allocate the object in a managed heap. And garbage collector automatically deallocates the objects that are not being used anymore from the managed heap “some time in the future”. 聽If you are already curious what is a managed heap, fret not. I will explain that too. But before that, lets talk about some fundamentals on memory.聽聽When we essentially write C#, we essentially use a virtual address space. Since you have a lot of processes in the same computer who shares the same memory (read your RAM here) and you would essentially need them not to overlap with one another. Each process then needs to address a specific set of the memory for them and thus you have your virtual address space mapped for each process. By default 32 bit computers has around 2GB user mode virtual address space. When you are actually allocating memory, you allocate memory on this virtual address space, not the physical memory. For this, the garbage collector works on this virtual space and frees up this virtual memory for you automatically. Neat, huh?

I need memory:

What actually happens when we essentially write something like the following:

    static void Main()
    {
        Cat cat = new Cat("Nerd");
    }

Looks like we are initiating a harmless cat with the name聽Nerd. When you compile this C Sharp compiler will generate a common intermediate language (IL/CIL) code聽so the JIT compiler in CLR can compile those for any possible machine configuration. You see, I said a lot of jargons, I didn’t bold them out because I’m not going to talk about them here. Now the intermediate code that is being generated here kind of looks like this:

IL_000a:        newobj instance void CilNew.Cat::.ctor (string)

It looks about right, we only care about the聽newobj instruction here. This specific instruction needs to do three things.

  1. Calculate the total amount of memory you require for the object.
  2. Look for space in the managed heap for space.
  3. When the object is created, return the reference to the caller and advance the next object pointer 聽to the next available slot on the managed heap.

Im quiet sure number 1 is very very easy to understand here. Why would we need to look for space in the managed heap then? Lets look at this first.

managed-heap

If you look at the example here, now it should be pretty clear to you what I meant. If the next object pointer doesn’t find enough space to fit the next object in, you would expect a聽OutOfMemoryException聽. This can also happen when you don’t have enough physical memory either. This picture also can mislead you. I will come to that now. You might think now Virtual address space is contiguous always. Well, it’s not. Virtual address space can be fragmented. This means that there are free blocks or holes among used blocks and the virtual memory manager has to find a big enough free block to allocate so you can instantiate your variable. So, even if you have 2GB virtual address space, this does not mean you have 2GB contiguously. If you ask the virtual memory manager for 2GB of space, it could fail due to the fact you dont have that amount of contiguous address space. But for regular explanations that picture will suffice well.

Now we know how objects are allocated and we spent some time on what is the managed heap and how objects are allocated on the managed heap. The reason we discussed about this is to make you understand why you need garbage collection and when it is triggered.

States of virtual memory:

There are three states of the virtual memory.聽Free state says this block of memory is available for allocation. When you request for allocation, it goes to聽Reserved state. Much like booking a hotel. Now your memory block is reserved for you but not used yet. And no one else can use this block either because you reserved it. When you finally use it, it goes to聽Committed聽state. In this state, the block of memory has a physical storage association.

The garbage collector kicks in:

There are definitely multiple conditions which are responsible for garbage collection. And you already know the very first one now. When you run out of space for a new allocation in the virtual address space. We are going to jump in and see what actually the garbage collector does in a very basic level.

Garbage collection happens in two stages.聽Mark and聽Sweep. The mark essentially searches for managed objects that are referenced in managed code. It will attempt to聽finalize objects that are unreachable. That is the first thing to do on聽sweep stage. The last work to do on聽sweep聽stage is to reclaim the memory of the聽unreachable objects now.

I know you are thinking what is聽managed code. We would come back to this in the journey. Don’t worry. For now, keep in your mind that garbage collector can only deal with聽managed聽code.

So, the technique is essentially to mark objects the program might be using and just clean off the rest one. But, how the garbage collector would know which objects it needs to clean? How would it decide which objects are unreachable. It does it using something called聽Object Graph which is not essentially under the context of this article. But I do have a nice representation to go with.

object-graph-pr-before-gc

Lets assume this is the situation in the heap. You have a managed heap like this and lets assume the garbage collector kicks in due to less memory. It would essentially look like the following after the collection.

object-graph-pr-after-gc

Now it should be evident to you what basically happens in a garbage collection from a birds eye view.聽Marked聽man needs finalization聽and then it leaves.

I still didn’t properly explain how you essentially get these marked objects. 聽To understand that properly, we need to understand about generations.

Generations inside the heap:

Generations inside the heap essentially dictates how long the object would be essentially needed. And thus it is divided into long-lived and聽short-lived objects. There are three generations here and the indexing starts from zero:

  1. Generation 0: This is the youngest generation and contains short-lived objects. Temporary and newly allocated objects live here. This is the part of the heap where garbage collection happens very frequently.
  2. Generation 1: This is essentially a buffer between generation 0 and generation 2. Generation 2 contains long-lived objects. Generation 1 essentially holds the objects who is still looking to be short-lived but survived generation 0.
  3. Generation 2: This is the generation of long-lived objects. These objects are usually objects that stays for long time in the process. Statics come first in mind. And a new object can be allocated straight to generation 2 instead of generation 0 if it’s really big. Like a big array with a lot of space allocation.

Garbage collections are generation specific but the collection is recursive up until the younger generation. So it clears generation 1, it would also clear generation 0. If GC clears generation 2, it would also go down to clear generation 1 and generation 0.

I used the word聽survive聽 a moment ago. What I wanted to say is if an object聽doesn’t get reclaimed/cleaned up during a sweep operation over a generation it gets promoted to the next generation. If survival rate is higher in a generation, GC tries to increase the threshold of allocation of that specific generation. So in the next cleanup the application gets a big size of memory freed.

One more thing to remember here. Garbage collector would stop any managed thread聽to work. So, it has to be quick and efficient unless you are looking at performance penalties.

Back to the code bits:

If you have survived up until now, you deserve to go back to the code bit at the beginning. The first thing I’m going to clear up is the managed vs unmanaged resources. Managed resources are directly under the control of the garbage collector. It is a result of managed code which would eventually compile to intermediate language. Unmanaged resources are resources your garbage collector don’t really know about. That includes, open files, open network connections and of course unmanaged memory. Now, if you are using C# classes to do these, most of the times these are almost managed. That means the managed code does the “dirty work” inside and you don’t have to clean up these yourselves. The garbage collector would clean up the managed wrapper and the managed wrapper would clean up the unmanaged code in the disposal process.

Now, lets go back to the word聽dispose here. How would I dispose something off my code. Is there a method somewhere, something I could use? Indeed there is. A dispose method implementation has essentially two variations. Since your garbage collection can’t handle unmanaged resources, you need to wrap them. The first technique is to wrap them under any class derived from SafeHandle class and use IDisposable聽聽interface to make it properly disposable. This very interface would expose the dispose() method you need and you would use that to dispose the resources yourself.

I explained in details how to do that in the next part.

To switch or not to switch

Now, the first thing that comes to mind when you are reading the title of this blog is a very “insightful” question that potentially dictates my reluctance to learn switch properly in C# even after all these years. Fret not, I’m the same old uncool dude who learns stuff late and in the process gets his ass kicked.

Today I want to go through the age old switch statement we all have been using. There’s a good number among us who prefers switch over an annoying if-else block. And I claim no crime there, not at all. Up until a couple of days ago I was a happy chump to use switch whenever I’m handling compile time constants like enums and writing if else blocks for my logical operation checks. Simple, happy as ever. All of that changed when my skyrim-ridden dull brain asked “Why there are two prominent branching paradigm here in this statically typed language” and kind of made a good point to find that out. I don’t remember what point my brain made at that time, sorry. But it’s my brain and I can’t deny much like deadpool cant.

deadpool

Let’s stay on focus, shall we? Lets go ahead and write a simple switch snippet like the following:

    public class Program
    {
        enum WhoGivesACrap
        {
            I_do,
            Nope_I_dont,
            Maybe_NotSure
        }
        static void Main(string[] args)
        {
            WhoGivesACrap whoGivesACrap = WhoGivesACrap.I_do;

            switch(whoGivesACrap)
            {
                case WhoGivesACrap.I_do:
                    System.Console.WriteLine($"{whoGivesACrap}");
                    break;
                case WhoGivesACrap.Maybe_NotSure:
                    System.Console.WriteLine($"{whoGivesACrap}");
                    break;
                case WhoGivesACrap.Nope_I_dont:
                    System.Console.WriteLine($"{whoGivesACrap}");
                    break;
            }
        }
    }

Now, this is definitely the first day at C# programming grade code. Dull, blasphemous and quiet frankly not worth of any attention. Same thoughts as mine to be honest. Thus I kept looking, booted up聽ildasm聽and asked what we can we see inside. Now, I can post the full de-assembled MSIL code here but that won’t make much of sense. Lets look on the parts we really want to look.

//000014:
//000015:             switch(whoGivesACrap)
    IL_0003:  ldloc.0
    IL_0004:  stloc.1
    .line 16707566,16707566 : 0,0 ''
//000016:             {
//000017:                 case WhoGivesACrap.I_do:
//000018:                     System.Console.WriteLine($"{whoGivesACrap}");
//000019:                     break;
//000020:                 case WhoGivesACrap.Maybe_NotSure:
//000021:                     System.Console.WriteLine($"{whoGivesACrap}");
//000022:                     break;
//000023:                 case WhoGivesACrap.Nope_I_dont:
//000024:                     System.Console.WriteLine($"{whoGivesACrap}");
//000025:                     break;
//000026:             }
//000027:         }
//000028:     }
//000029: }
    IL_0005:  ldloc.1
    IL_0006:  switch     (
                          IL_0019,
                          IL_0049,
                          IL_0031)
    IL_0017:  br.s       IL_0061

    .line 18,18 : 21,66 ''
//000018:                     System.Console.WriteLine($"{whoGivesACrap}");

I opted for dumping with my C# source code. And the thing that catches my eye is the聽switch聽 invocation with the three jump locations. And as my enums were adjacent it makes sense. CIL聽switchessentially create a jump table. The three arguments it takes are essentially jump locations which will be compared against my enums. Cool, at least now I have an answer why it is different than if-else-if-else. Remember I didn’t say聽if-else block because it makes more sense to do聽if-else in this fashion than checking else for no apparent reason.

If you are still not bored enough why don’t you go and have a look here?

Now, I also thought this would be the end of it. But the聽voices in my head reminded me to do one more thing. And that’s using non-adjacent values. Thus I modified my enum in the following fashion.

        enum WhoGivesACrap
        {
            I_do = 17,
            Nope_I_dont = 57,
            Maybe_NotSure = 945
        }

And hooked up聽ildasm again to figure out what happened this time. Now, my values are non adjacent. It doesn’t really make sense anymore to create around 900+ entry jump table.

//000014:
//000015:             switch(whoGivesACrap)
    IL_0004:  ldloc.0
    IL_0005:  stloc.1
    .line 16707566,16707566 : 0,0 ''
//000016:             {
//000017:                 case WhoGivesACrap.I_do:
//000018:                     System.Console.WriteLine($"{whoGivesACrap}");
//000019:                     break;
//000020:                 case WhoGivesACrap.Maybe_NotSure:
//000021:                     System.Console.WriteLine($"{whoGivesACrap}");
//000022:                     break;
//000023:                 case WhoGivesACrap.Nope_I_dont:
//000024:                     System.Console.WriteLine($"{whoGivesACrap}");
//000025:                     break;
//000026:             }
//000027:         }
//000028:     }
//000029: }
    IL_0006:  ldloc.1
    IL_0007:  ldc.i4.s   17
    IL_0009:  beq.s      IL_001e

    IL_000b:  br.s       IL_000d

    IL_000d:  ldloc.1
    IL_000e:  ldc.i4.s   57
    IL_0010:  beq.s      IL_004e

    IL_0012:  br.s       IL_0014

    IL_0014:  ldloc.1
    IL_0015:  ldc.i4     0x3b1
    IL_001a:  beq.s      IL_0036

    IL_001c:  br.s       IL_0066

    .line 18,18 : 21,66 ''
//000018:                     System.Console.WriteLine($"{whoGivesACrap}");

And I wasn’t wrong. Since the values are non-adjacent now聽CSC opted for loading the enums separately and used beq.s which stands for聽branch-if-equal in short form. Technically this looks like a vanilla if-else-if block. Although I can’t possibly say聽CSC would generate opcodes following this and this only.

I know this whole thing might sound insanely boring while聽performance聽wise this would only make a minuscule difference. Still, it’s always fun to answer the聽voices inside my head and they are much happier when they have something to hold against when they ask聽why.

Until next time!

Asynchrnous Programming in C# Cheat Sheet

Tip: Dont go for Async Void

You get possibly three return types for async methods and those would be

  • Task
  • Task < T >
  • void

Its always better if you can avoid the void.

Reason:

Async Void methods were made possible so one can have async event handlers. Exceptions thrown out of these are actually handled in the Synchronization context that was active at that time, meaning you wont be able to “catch” it with a “catch”. You can definitely catch those in App.UnhandledException or similiar all unhandled exception catching scenarios. Plus, its not testable too.

If you go for returning Task you will see your async methods are returning a Task object which essentially has the exceptions noted inside of it.

Workaround:

In case of stuff like async event handlers, the best thing to do would be is to put the actual code logic in a separate awaited method so you can test it whenever you want.

Tip: Once Async always go async

Async codes are written better if they are written from the top to the bottom in an all async paradigm, meaning its always better to wrap an async method in another async method all the way to the bottom. If you wrap up a little async code in your sync code context, you might end up in a deadlock.

public static class DeadlockDemo
{
  private static async Task DelayAsync()
  {
    await Task.Delay(1000);
  }
  // This method causes a deadlock when called in a GUI or ASP.NET context.
  public static void Test()
  {
    // Start the delay.
    var delayTask = DelayAsync();
    // Wait for the delay to complete.
    delayTask.Wait();
  }
}

This piece of code would end up in a deadlock in GUI or ASP.net apps. Because when you await a Task the current context is captured so it can be resumed on the current context after the awaiting is done. The context is usually the current SynchronizationContext which is essentially the TaskScheduler. In Asp.net or GUI app youre only supposed to run a single chunk of code at a time. In this case the DelayAsync await is completed it is trying to complete the rest of the code after await in the captured context. This context has already a thread in it and waiting for the async call to be finished. They are waiting on each other = deadlock.

In case of a console app, this would execute just fine. Because it has a thread pool SynchronizationContext so it would execute the rest of the async method in a separate thread.

A good thing to remember here is that if you await a async method only the first exception occured would be rethrown. If you block in synchronously you’d get an AggregateException with all the exceptions in it

 

Tip: Configuring await context

When you have a lot of incy wincy bits of async code, your GUI app might end up in a situation where most of the time its busy handling those async events. This can lead to performance issues.

Solution and Example:

Using ConfigureAwait at the end of your async call might help you in this case. Follow the following example:

async Task MyMethodAsync()
{
  // Code here runs in the original context.
  await Task.Delay(1000);
  // Code here runs in the original context.
  await Task.Delay(1000).ConfigureAwait(
    continueOnCapturedContext: false);
  // Code here runs without the original
  // context (in this case, on the thread pool).
}

You can definitely see here that we are denying to run the rest of the async method after the await in the same context. Now it would use a thread pool synchrnizing context for your code and esssentially would make your code deadlock free and a tad smoother. Very handy for UWP app people.

Warning

For GUI people, dont use ConfigureAwait everywhere! Please only use it when the rest of the code doesnt handle any GUI events (databound update, GUI updates) and for ASP.net people, dont use it if the rest of the code uses HttpContext of that time.

And finally, If you’re not a TLDR; guy and need more please read this