Tuesday, February 25, 2025

Efficient Parallel Processing in .NET: Using Parallel.ForEach, IServiceScopeFactory, and ConcurrentBag

Parallel processing in .NET can significantly improve performance when dealing with large collections. However, when working with scoped dependencies and thread-safe collections, managing them properly is crucial. This blog explores how to use Parallel.ForEach, IServiceScopeFactory, and ConcurrentBag efficiently.

Why Use Parallel.ForEach?
Parallel.ForEach executes iterations in parallel, utilizing multiple CPU cores to improve performance. However, it does not automatically handle scoped dependencies from IServiceScopeFactory, which is essential when working with services like DbContext in ASP.NET Core.

Why IServiceScopeFactory?
Since DbContext and other scoped services should not be shared across multiple threads, using IServiceScopeFactory ensures each thread gets its own service scope.

Why ConcurrentBag?
When dealing with concurrent operations, ConcurrentBag is a thread-safe collection that allows multiple threads to add or retrieve items without conflicts.


Example:

Code Snippet


Key Takeaways
- Use Parallel.ForEach for performance gains when processing large collections.
- Utilize IServiceScopeFactory to create scoped services inside parallel loops.
- Store results in ConcurrentBag to ensure thread safety when collecting data.
This approach ensures efficient parallel execution while maintaining the integrity of scoped services in .NET. πŸš€

Friday, February 14, 2025

πŸš€ Oops! Pushed to develop by Mistake? Here’s a Quick Fix! πŸš€

πŸš€ Oops! Pushed to develop by Mistake? Here’s a Quick Fix! πŸš€
We've all been there—accidentally pushing changes to the develop branch instead of a feature branch. Before you panic, there's a simple way to undo it gracefully using Git.

πŸ”„ The Quick Fix
If you've mistakenly pushed your latest commit to develop, run the following command: 1️⃣ Save the commit/changes

Code Snippet


πŸ”Ή What does this do?
✅ Moves the latest commit to staged changes without deleting it.
✅ Allows you to fix things before re-committing or switching branches.

2️⃣ Discard the Commit Completely
If you want to undo the commit entirely (⚠️ This will remove all changes!):

Discard the Last Commit


πŸ”„ Next Steps
Switch to the Correct Branch and Recommit
If you meant to push the changes to a different branch:

Move Changes to Correct Branch


😊Like that we can revert our mistake😊

Wednesday, February 12, 2025

How to handle when code push accidently in deleted branch

Have you ever pushed your code, only to realize the branch was deleted? 😱 No worries—your work isn't lost! Git keeps a history of all commits, and you can easily recover your code.
πŸš€ Steps to Recover Your Deleted Branch
1️⃣ Check Your Git Log Even if a branch is deleted, the commits still exist. Run:

Code Snippet

This will show a list of commit hashes with their messages.
2️⃣ Find Your Last Commit Look for the commit related to your deleted branch
3️⃣ Restore Your Branch Once you have the commit hash, recreate the branch:

Code Snippet

Note : Instead of "abc1234" write "your hashcode" and "recovered-branch" write your "new branch name"

😊Now you can push your code in that branch and you can able to create PR.😊

Sunday, February 9, 2025

How to Implement In Memory Caching in .net

 

Introduction

In modern web applications, performance is key. Fetching data repeatedly from a database can lead to increased response times and higher server load. One effective way to optimize performance is by using in-memory caching to store frequently accessed data. In this blog, we will explore how to integrate IMemoryCache in an ASP.NET Core Web API project to efficiently handle CRUD operations for a Student entity.

What is In-Memory Caching?

In-memory caching is a mechanism that temporarily stores frequently accessed data in memory, reducing the need to retrieve it from the database each time. ASP.NET Core provides IMemoryCache, which is a simple, high-performance, and thread-safe cache.

Setting Up the Project

To demonstrate in-memory caching, let’s build an ASP.NET Core Web API with a StudentController that performs CRUD operations using Entity Framework Core.

1. Install Required Dependencies

Ensure you have the necessary NuGet packages installed in your ASP.NET Core project:




2. Add Model and  AppDb Context file



Student Model

AppDb Context File

3. Add in Appsettings.json just below of AllowedHosts by put comma

Connection String

4. Add Settings

Program.cs

5. Add-Migration and Update-database run two commands
6. add Controller with name Student

Student Controller

6. SetSlidingExpiration: refreseh if no activity in 10 min
SetAbsoluteExpiration : always refresh after 1 hour

Expalin memory Cache options

Note: In this i used semaphoreslim for single process optimised the in memory cache. I am updating the in memory cache when add and update and delete. also this approch is helpfull for single server or small level applications. for multiserver or high level application we should go with distributed cache technique like redis so our ram not effected to much.

Clone this poc:InMemoryCachePOC

Semaphore Vs Semaphore Slim

 

Semaphore vs SemaphoreSlim in C#

What is a Semaphore?

A Semaphore is a synchronization primitive used to control access to a shared resource by multiple threads. It works by maintaining a count that represents the number of available slots for accessing the resource. When a thread enters, the count decreases, and when it leaves, the count increases.

What is SemaphoreSlim?

SemaphoreSlim is a lightweight, managed implementation of Semaphore, introduced in .NET Framework 4. It provides better performance and is optimized for cases where a semaphore is needed within a single process.


Why Use Semaphore and SemaphoreSlim?

  1. To limit concurrent access to a resource
    Example: Controlling access to a database connection pool or an API rate limit.

  2. To prevent race conditions
    Example: Ensuring that only a limited number of threads can modify a shared collection at a time.

  3. To manage multi-threaded access in an efficient way
    Example: Restricting simultaneous file writes to avoid corruption.


    Semaphore vs SemaphoreSlim - Key Differences πŸš€

    FeatureSemaphore 🏒SemaphoreSlim πŸš€
    ScopeWorks across multiple processesWorks within a single process
    ImplementationUses OS-level (kernel-based) synchronizationUses user-mode synchronization (managed by .NET)
    PerformanceSlower due to kernel transitionsFaster as it avoids kernel overhead
    Async SupportDoes not support async/awaitSupports async/await for better responsiveness
    Use CaseInter-process synchronization (e.g., shared system resources)Within-process synchronization (e.g., limiting concurrent API calls, database access)
    Blocking vs Non-BlockingBlocks threads while waitingUses async wait, avoiding thread blocking
    Wait Handle Support✅ Supports WaitOne(), WaitAll()❌ Does not support WaitHandle methods

    When to Use?

    Use Semaphore when you need to synchronize across different applications (e.g., OS-wide named semaphores).
    Use Semaphore Slim when you need a lightweight, high-performance synchronization within a single process, especially with async/await.

    Note: semaphore slim  I used in in memory caching for single process so save dB calls and we give users to fast response.
    while semaphore is used for allow or control to multiple processes like if we have to run only two than we can control with that 
    InMemory caching: In Memory Caching in .Net

Wednesday, February 5, 2025

How .NET API Uses RAM?

✅ Application Start: Code and dependencies are loaded into RAM.

✅ CLR Loads Assemblies: JIT compiles and stores DLLs in RAM.

✅ Memory Allocation: Stack (method calls) & Heap (objects, DI, cache).

✅ Caching (Boosts Speed!): Frequently accessed data is stored in RAM.

✅ Handling HTTP Requests: Kestrel/IIS processes requests in memory.

✅ Garbage Collection: Frees up unused objects, optimizing RAM.

✅ (Optional) In-Memory Database: Uses RAM for high-speed transactions.


πŸ”Ή Complete Process in a Simple Diagram!


+----------------------------------------------------+

| 🟒 APPLICATION START (Loaded in RAM) |

| - Run API: (dotnet run / IIS / Kestrel) |

| - .NET Runtime (CLR) loads code into RAM |

+----------------------------------------------------+

|

v

+----------------------------------------------------+

| πŸ”„ CLR LOADS ASSEMBLIES (Stored in RAM) |

| - JIT (Just-In-Time) compiles code |

| - Dependencies & DLLs loaded into memory (RAM) |

+----------------------------------------------------+

|

v

+----------------------------------------------------+

| πŸ’Ύ MEMORY ALLOCATION (RAM Usage) |

| - Stack: Stores method calls, local variables |

| - Heap: Stores objects, services, cache data |

| - DI Container: Manages service lifetimes |

+----------------------------------------------------+

|

v

+----------------------------------------------------+

| ⚡ CACHING (Improves Speed, Uses RAM) |

| - In-Memory Cache (MemoryCache, Singleton) |

| - Distributed Cache (Redis, NCache) (Optional) |

| - Reduces Database Calls, Increases Performance |

+----------------------------------------------------+

|

v

+----------------------------------------------------+

| 🌐 HANDLING HTTP REQUESTS |

| - Kestrel/IIS Listens for Requests |

| - Middleware (Auth, Logging, Compression) |

| - Controllers Execute Business Logic |

+----------------------------------------------------+

|

v

+----------------------------------------------------+

| πŸ—‘️ GARBAGE COLLECTION (Frees RAM) |

| - Gen 0: Short-lived objects (frequent cleanup) |

| - Gen 1 & 2: Long-lived objects (less cleanup) |

| - Optimizes RAM usage, prevents memory leaks |

+----------------------------------------------------+

|

v

+----------------------------------------------------+

| πŸ›’️ (OPTIONAL) IN-MEMORY DATABASE |

| - EF Core In-Memory / SQLite (Stored in RAM) |

| - Fast Reads/Writes, No Disk I/O |

+----------------------------------------------------+

πŸ’‘ Why This Matters?

πŸ”Ή Faster performance with in-memory caching.

πŸ”Ή Reduced database calls, improving scalability.

πŸ”Ή Optimized RAM usage via Garbage Collection.


Saturday, February 1, 2025

Struct Vs Union in c#

In C#, both struct and union are used to create value types, but they are different significantly in memory allocation and usage. ________________________________________ 
1. struct in C# A struct in C# is a value type that contains multiple fields, where each field gets its own memory space. Structs are useful for representing small data structures that do not require reference semantics. 
Memory Allocation in struct Each field inside the struct has its own memory. The size of a struct is the sum of its field sizes (considering padding and alignment). 
Example of struct

Code Snippet

Memory Layout 
Field Type Size Id int 4 bytes Salary double 8 bytes Total 12 bytes (or more with padding) 
When to Use struct? 
✔️ Small, lightweight data structures 
✔️ When no need for inheritance 
✔️ When working with performance-sensitive applications (to avoid heap allocations) ________________________________________
  2. union in C# (Using StructLayout and FieldOffset) C# does not have a direct union like C/C++, but you can create a union-like structure using [StructLayout(LayoutKind.Explicit)] and [FieldOffset] attributes.
  How Does a union Work? 
• All fields share the same memory. 
• The size of the union is equal to the size of the largest field.
 • Writing to one field overwrites the other. Example of union in C#

Code Snippet

Output (may vary due to memory representation) 

intValue: 100, floatValue: 1.401298E-43, charValue: d

intValue: 1091567616, floatValue: 9.5, charValue: e

intValue: 65, floatValue: 9.10844E-44, charValue: A


     Why does this happen?
·        When intValue = 100, the same memory is interpreted as a float and a char.
·        When floatValue = 9.5f, the same memory gets rewritten.
·        When charValue = 'A', it affects the integer and float values.
Memory Layout of a union

Field

Type

Size (bytes)

intValue

int

4

floatValue

float

4 (shared)

charValue

char

2 (shared within 4 bytes)

Total Memory Used

4 bytes (size of the largest field)

When to Use a union?
✔️ Memory-efficient storage (especially useful for low-level programming)
✔️ Interop with unmanaged C/C++ code (e.g., working with hardware, binary data)
✔️ Working with bitwise operations
🚨 Caution: Accessing a different field than the last written one may produce undefined behavior.
πŸš€ Key Differences Between struct and union in C#

Feature

struct

union (via FieldOffset)

Memory Allocation

Each field gets separate memory

All fields share the same memory

Size

Sum of all field sizes (considering alignment)

Size of the largest field

Usage

When fields hold independent values

When only one field is used at a time

Performance

Faster but consumes more memory

Memory-efficient but risky

Common Use Cases

Small objects, lightweight data storage

Interoperability with unmanaged code, memory optimization


Conclusion
·    Use struct when you need a lightweight data type where each field has its own storage.
·   Use union (via StructLayout + FieldOffset) when you need memory-efficient structures where fields share the same memory.



How to Do Cross-Browser Testing on Windows — Including Safari via Playwright

To test follow few steps: Step 1. Install node Step 2. create Folder and run these commands commands Copy Code ...