Important Facts of Asynchronous Programming in .NET

Modern apps make extensive use of file and networking I/O. I/O APIs traditionally block by default, resulting in poor user experiences and hardware utilization unless you want to learn and use challenging patterns.

Task-based async APIs and the language-level asynchronous programming model invert this model, making async execution the default with few new concepts to learn.

Async code has the following characteristics:

  • Handles more server requests by yielding threads to handle more requests while waiting for I/O requests to return.
  • Enables UIs to be more responsive by yielding threads to UI interaction while waiting for I/O requests and by transitioning long-running work to other CPU cores.
  • Many of the newer .NET APIs are asynchronous.
  • It’s easy to write async code in .NET

One of the main advantages of using asynchronous methods is with I/O-based code.

By doing an await, you can let a thread be reused to do other work while the I/O is in flight.

The biggest misunderstanding about Asynchronous programming in many developers is asynchronous method automatically spawns a new thread, and that is not the case.

Recent improvements Microsoft has made towards Asynchronous programming is “Generalized Async Return Types

This means that you’re no longer limited to using Task or Task<T> as the return type for an asynchronous method. As long as the return type satisfies the asynchronous pattern, you’re good. Using this new ValueTask, you can avoid memory allocations, which can help in addressing performance issues.

Top Nuget Packages that Microsoft recommend for asynchronous programming are “System.Collections.Concurrent” and “System.Collections.Immutable“.

System.Collections.Immutable provides collections that allow a developer to use a collection (e.g. ConcurrentBag or ConcurrentDictionary) in a concurrent fashion safely. Therefore, the developer doesn’t need to do their own locking mechanisms to use the collection. Immutable collections allow developers to share collections safely because updates are only seen by the code that made the update.

Avoid void as a return type for asynchronous methods at all costs.

The only time it’s valid to do this is with an event handler. Otherwise, asynchronous methods should always return a Task type.

Immutable structures are very important when working with concurrent programming.

The main advantage with immutable data types is that you can share them across multiple tasks without worrying about synchronizing their contents. By their definition, they’re immutable, so if a task decides to “change” an immutable object, it will get a new version of that object. If another task has a reference to the original immutable object, it doesn’t change.

Take advantage of C# features to write immutable structures.

This means defining fields with the readonly keyword and properties that only have getters (not even private setters). Also, C# now allows you to specify a method parameter with the in keyword, which means that reference cannot be changed.

That’s all for now. I hope these facts will help you while doing Asynchronous Programming for your projects 🙂

How To Do Production Debugging on the Fly

A case study in swift .NET application debugging using a variety of free tools that can help keep a client happy.
What Is Production Debugging?
Production debugging is all about solving customer-facing issues that aren’t easily reproducible. Take, for example, a common problem of a fast-food restaurant kiosk that goes offline with a blue screen of death. That restaurant loses its ability to accept orders from customers, of course, but it also can disrupt workflows and bring chaos to other parts of the business operations. If the problem can be traced to a hardware issue, hardware can be quickly replaced. But in the case of software issues, replacing hardware will be of no help. Software vendors have to fix the issue, and that, in turn, requires being able to reproduce the scenario first.

Read full article – Click

Hope this will help !!!

Automated acceptance testing with Cucumber for .NET and JAVA

One of the biggest problems in software development is communication. Although we have a lot of technology at hand, the more complex a project is, the harder it is to communicate efficiently. In order to improve the interaction between clients, project managers, analysts and developers, a definition of the requirements is needed.

Another important part is testing. With the ever-growing complexity of software, acceptance testing becomes increasingly important. Manual acceptance testing is very time consuming and error-prone though.

Full Article:

Happy Programming !!!
Jay Ganesh

Partitioning Your Code Base Through .NET Assemblies and Visual Studio Projects

This article is aimed at

  • Providing a list of DO and DON’T when it comes to partitioning a code base into .NET assemblies and Visual Studio projects.
  • Shedding light on.NET code componentization and packaging.
  • Suggesting ways of organizing the development environment more effectively.

The aim of this is to increase the speed of .NET developer tools, including VS and C#/VB.NET compilers, by up to an order of magnitude. This is done merely by rationalizing the development of a large code base. This will significantly increase productivity and decrease the maintenance cost of the .NET application .

This advice is gained from years of real-world consulting and development work and has proved to be effective in several settings and on many occasions..

Read more …

Hope this will helps !!!

Jay Ganesh

.Net Memory Management & Garbage Collection

I have seen one video from red-gate about the memory management in .net when I was surfing about ANTS memory profiler. So I thought why not I create article based on this facts & help others to know how Garbage collector actually works.


The Microsoft .NET common language runtime requires that all resources be allocated from the managed heap. Objects are automatically freed when they are no longer needed by the application.

When a process is initialized, the runtime reserves a contiguous region of address space that initially has no storage allocated for it. This address space region is the managed heap. The heap also maintains a pointer. This pointer indicates where the next object is to be allocated within the heap. Initially, the pointer is set to the base address of the reserved address space region.

Garbage collection in the Microsoft .NET common language runtime environment completely absolves the developer from tracking memory usage and knowing when to free memory. However, you’ll want to understand how it works. So let’s do it.

Topics Covered

We will cover the following topics in the article

  1. Why memory matters
  2. .Net Memory and garbage collection
  3. Generational garbage collection
  4. Temporary Objects
  5. Large object heap & Fragmentation
  6. Finalization
  7. Memory problems

1) Why Memory Matters

Insufficient use of memory can impact

  • Performance
  • Stability
  • Scalability
  • Other applications

Hidden problem in code can cause

  • Memory leaks
  • Excessive memory usage
  • Unnecessary performance overhead

2) .Net Memory and garbage collection

.Net manages memory automatically

  • Creates objects into memory blocks(heaps)
  • Destroy objects no longer in use

Allocates objects onto one of two heaps

  • Small object heap(SOH) – objects < 85k
  • Large object heap(LOH) – objects >= 85k

You allocate onto the heap whenever you use the “new” keyword in code

Small object heap (SOH)

  • Allocation of objects < 85k – Contiguous heap – Objects allocated consecutively
  • Next object pointer is maintained – Objects references held on Stack, Globals, Statics and CPU register
  • Objects not in use are garbage collected



Next, How GC works in SOH?

GC Collect the objects based on the following rules:

  • Reclaims memory from “rootless” objects
  • Runs whenever memory usage reaches certain thresholds
  • Identifies all objects still “in use”
    • Has root reference
    • Has an ancestor with a root reference
  • Compacts the heap
    • Copies “rooted” objects over rootless ones
    • Resets the next object pointer
  • Freezes all execution threads during GC
    • Every GC runs it   hit the performance of your app



3) Generational garbage collection

Optimizing Garbage collection

  • Newest object usually dies quickly
  • Oldest object tend to stay alive
  • GC groups objects into Generations
    • Short lived – Gen 0
    • Medium – Gen 1
    • Long Lived – Gen 2
  • When an object survives a GC it is promoted to the next generation
  • GC compacts Gen 0 objects most often
  • The more the GC runs the bigger the impact on performance





Here object C is no longer referenced by any one so when GC runs it get destroyed & Object D will be moved to the Gen 1 (see figure-5). Now Gen 0 has no object, so when next time when GC runs it will collect object from Gen 1.





Here when GC runs it will move the object D & B to Gen 2 because it has been referenced by Global objects & Static objects.



Here when GC runs for Gen 2 it will find out that object A is no longer referenced by anyone so it will destroy it & frees his memory. Now Gen 2 has only object D & B.

Garbage collector runs when

  • Gen 0 objects reach ~256k
  • Gen 1 objects reach ~2Meg
  • Gen 2 objects reach ~10Meg
  • System memory is low

Most objects should die in Gen 0.

Impact on performance is very high when Gen 2 run because

  • Entire small object heap is compacted
  • Large object heap is collected

4) Temporary objects

  • Once allocated objects can’t resize on a contiguous heap
  • Objects such as strings are Immutable
    • Can’t be changed, new versions created instead
    • Heap fills with temporary objects

Let us take example to understand this scenario.

Figure – 8


After the GC runs all the temporary objects are destroyed.



5) Large object heap & Fragmentation

Large object heap (LOH)

  • Allocation of object >=85k
  • Non contiguous heap
    • Objects allocated using free space table
  • Garbage collected when LOH Threshold Is reached
  • Uses free space table to find where to allocate
  • Memory can become fragmented



After object B is destroyed free space table will be filled with a memory address which has been available now.



Now when you create new object, GC will check out which memory area is free or available for our new object in LOH. It will check out the Free space table & allocate object where it fit.



6) Object Finalization

  • Disk, Network, UI resources need safe cleanup after use by .NET classes
  • Object finalization guarantees cleanup code will be called before collection
  • Finalizable object survive for at least 1 extra GC & often make it to Gen 2
  • Finalizable classes have a
    • Finalize method(c# or
    • C++ style destructor (c#)

Here are the guidelines that help you to decide when to use Finalize method:

  • Only implement Finalize on objects that require finalization. There are performance costs associated with Finalize methods.
  • If you require a Finalize method, you should consider implementing IDisposable to allow users of your class to avoid the cost of invoking the Finalize method.
  • Do not make the Finalize method more visible. It should be protected, not public.
  • An object’s Finalize method should free any external resources that the object owns. Moreover, a Finalize method should release only resources that are held onto by the object. The Finalize method should not reference any other objects.
  • Do not directly call a Finalize method on an object other than the object’s base class. This is not a valid operation in the C# programming language.
  • Call the base.Finalize method from an object’s Finalize method.

Note: The base class’s Finalize method is called automatically with the C# and the Managed Extensions for C++ destructor syntax.

Let see one example to understand how the finalization works.

Each figure itself explain what is going on & you can clearly see how the finalization works when GC run.











For more information on Finalization refer the following links:

How to minimize overheads

Object size, number of objects, and object lifetime are all factors that impact your application’s allocation profile. While allocations are quick, the efficiency of garbage collection depends (among other things) on the generation being collected. Collecting small objects from Gen 0 is the most efficient form of garbage collection because Gen 0 is the smallest and typically fits in the CPU cache. In contrast, frequent collection of objects from Gen 2 is expensive. To identify when allocations occur, and which generations they occur in, observe your application’s allocation patterns by using an allocation profiler such as the CLR Profiler.

You can minimize overheads by:

  • Avoid Calling GC.Collect
  • Consider Using Weak References with Cached Data
  • Prevent the Promotion of Short-Lived Objects
  • Set Unneeded Member Variables to Null Before Making Long-Running Calls
  • Minimize Hidden Allocations
  • Avoid or Minimize Complex Object Graphs
  • Avoid Preallocating and Chunking Memory

Read more:

7) Common Memory Problems

  • Excessive RAM footprint
    • App allocates objects too early or for too long using more memory than needed
    • Can affect other app on system
  • Excessive temporary object allocation
    • Garbage collection runs more frequently
    • Executing threads freeze during garbage collection
  • Memory leaks
    • Overlooked root references keep objects alive (collections, arrays, session state, delegates/events etc)
    • Incorrect or absent finalization can cause resource leaks

References & other useful articles related to this topic:

Hope this help

Jay Ganesh

Shout it kick it on