Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Saturday, April 18, 2026

Monitor, Mutex, and lock in Multithreading Windows Services C#

Monitor, Mutex, and lock are fundamental synchronization mechanisms in C#. Let’s go step by step so you can explain them clearly in your blog or interview.


🔹 1. The Problem They Solve

When multiple threads run in parallel, they may try to access or modify the same shared resource (like a file, database record, or variable).
This can lead to race conditions (unexpected results due to simultaneous access).

Solution → Synchronization mechanisms ensure only one thread at a time can access critical sections of code.


🔹 2. lock Keyword

  • Definition: A simplified way to use Monitor in C#. It ensures that only one thread enters a block of code at a time.
  • How it works: Internally, lock uses Monitor.Enter and Monitor.Exit.
  • Usage:
static object _lock = new object();
static int counter = 0;

lock (_lock)
{
    counter++;
    Console.WriteLine($"Counter: {counter}");
}
  • Step-by-step:
    1. Thread requests access to the block.
    2. If another thread is inside, it waits.
    3. Once the block is free, the thread enters.
    4. When finished, the lock is released.

Best for: Simple critical sections inside the same process.


🔹 3. Monitor

  • Definition: Provides more control than lock. It allows threads to wait and signal each other.
  • Key Methods:
    • Monitor.Enter(obj) → Acquire lock.
    • Monitor.Exit(obj) → Release lock.
    • Monitor.Wait(obj) → Release lock temporarily and wait.
    • Monitor.Pulse(obj) → Signal one waiting thread.
    • Monitor.PulseAll(obj) → Signal all waiting threads.
  • Usage:
static object _lock = new object();
static int counter = 0;

Monitor.Enter(_lock);
try
{
    counter++;
    Console.WriteLine($"Counter: {counter}");
}
finally
{
    Monitor.Exit(_lock); // Always release in finally
}
  • Step-by-step:
    1. Thread enters using Monitor.Enter.
    2. Executes critical section.
    3. Can use Wait and Pulse for coordination.
    4. Releases lock with Monitor.Exit.

Best for: Complex scenarios where threads need to communicate (producer-consumer patterns).


🔹 4. Mutex

  • Definition: A synchronization primitive that works across processes (not just threads in the same process).
  • Usage:
using System.Threading;

class Program
{
    static Mutex mutex = new Mutex();

    static void Main()
    {
        if (mutex.WaitOne())
        {
            try
            {
                Console.WriteLine("Mutex acquired.");
                Thread.Sleep(2000); // simulate work
            }
            finally
            {
                mutex.ReleaseMutex();
                Console.WriteLine("Mutex released.");
            }
        }
    }
}
  • Step-by-step:
    1. Thread/process requests the mutex using WaitOne().
    2. If available, it enters; otherwise, it waits.
    3. Executes critical section.
    4. Releases mutex with ReleaseMutex().

Best for: Synchronizing resources across multiple processes (e.g., two different applications accessing the same file).


🔹 5. Summary Comparison

Feature lock Monitor Mutex
Scope Threads in same process Threads in same process Threads across processes
Ease of Use Very simple More complex Moderate
Extra Features None Wait/Pulse signaling Cross-process synchronization
Performance Fastest Slightly slower Slowest (OS-level object)
Best Use Case Simple critical sections Complex thread coordination Multi-process resource sharing

🎯 Conclusion

  • Use lock for simple thread safety.
  • Use Monitor when you need advanced coordination between threads.
  • Use Mutex when synchronization must extend across multiple processes.

By explaining these step-by-step, you’ll show both conceptual clarity and practical expertise—perfect for interviews and blog readers.



Sunday, November 2, 2025

🧩 Façade Design Pattern in C# – Simplifying Complex Systems

🔍 What is the Façade Design Pattern?

The Façade Design Pattern is a structural design pattern that provides a simplified interface to a complex subsystem of classes, libraries, or frameworks.
In simple terms, it hides the complexity of multiple interdependent systems behind a single, easy-to-use interface.

Think of a hotel receptionist — you don’t directly talk to housekeeping, room service, or maintenance. The receptionist (Façade) takes your request and communicates with the right departments internally.


🧠 Intent of the Façade Pattern

  • Simplify interaction between client and complex subsystems.

  • Reduce dependencies between client and internal components.

  • Make the system easier to use and maintain.


🧩 Structure (UML Conceptually)

Client → Facade → SubsystemA → SubsystemB → SubsystemC

The Client interacts with the Facade, which delegates calls to one or more Subsystems.


💻 C# Example: Home Theater System

Let’s say you’re building a Home Theater Application that involves multiple components:

  • DVD Player

  • Projector

  • Sound System

  • Lights

Instead of the client calling all these subsystems directly, we can use a Facade class to control them with a single method call.

Step 1: Subsystems

public class DVDPlayer { public void On() => Console.WriteLine("DVD Player On"); public void Play(string movie) => Console.WriteLine($"Playing '{movie}'"); public void Off() => Console.WriteLine("DVD Player Off"); } public class Projector { public void On() => Console.WriteLine("Projector On"); public void SetInput(string source) => Console.WriteLine($"Projector input set to {source}"); public void Off() => Console.WriteLine("Projector Off"); } public class SoundSystem { public void On() => Console.WriteLine("Sound System On"); public void SetVolume(int level) => Console.WriteLine($"Volume set to {level}"); public void Off() => Console.WriteLine("Sound System Off"); } public class Lights { public void Dim(int level) => Console.WriteLine($"Lights dimmed to {level}%"); }

Step 2: Façade Class

public class HomeTheaterFacade { private readonly DVDPlayer dvd; private readonly Projector projector; private readonly SoundSystem sound; private readonly Lights lights; public HomeTheaterFacade(DVDPlayer dvd, Projector projector, SoundSystem sound, Lights lights) { this.dvd = dvd; this.projector = projector; this.sound = sound; this.lights = lights; } public void WatchMovie(string movie) { Console.WriteLine("Get ready to watch a movie..."); lights.Dim(10); projector.On(); projector.SetInput("DVD Player"); sound.On(); sound.SetVolume(5); dvd.On(); dvd.Play(movie); } public void EndMovie() { Console.WriteLine("Shutting down the home theater..."); dvd.Off(); sound.Off(); projector.Off(); lights.Dim(100); } }

Step 3: Client Code

class Program { static void Main() { var dvd = new DVDPlayer(); var projector = new Projector(); var sound = new SoundSystem(); var lights = new Lights(); var homeTheater = new HomeTheaterFacade(dvd, projector, sound, lights); homeTheater.WatchMovie("Avengers: Endgame"); Console.WriteLine("\n--- Movie Finished ---\n"); homeTheater.EndMovie(); } }

🧾 Output:

Get ready to watch a movie... Lights dimmed to 10% Projector On Projector input set to DVD Player Sound System On Volume set to 5 DVD Player On Playing 'Avengers: Endgame' --- Movie Finished --- Shutting down the home theater... DVD Player Off Sound System Off Projector Off Lights dimmed to 100%

🚀 Real-Time Use Cases of Façade Pattern

ScenarioHow Façade Helps
Banking SystemsSimplifies complex operations like fund transfers by combining multiple services (accounts, validation, notification) into one interface.
E-commerce CheckoutCombines inventory, payment, and order services into one checkout process.
Hotel Booking APIsWraps flight, hotel, and transport systems behind a single booking interface.
Logging or Notification SystemsProvides one class to log to multiple targets (database, file, email).
Azure / AWS SDK WrappersDevelopers use simplified API wrappers to avoid dealing with multiple low-level SDK services.

⚖️ Advantages of the Façade Pattern

✅ Simplifies complex systems for clients
✅ Reduces coupling between client and subsystems
✅ Improves code readability and maintenance
✅ Makes the system more modular


⚠️ Disadvantages

❌ Overuse may hide useful functionality from the client
❌ Can become a "God Object" if it grows too large
❌ Difficult to maintain if subsystems frequently change


💡 Best Practices

  • Use when you have a complex system with multiple dependencies.

  • Keep the Facade thin — it should only simplify, not duplicate logic.

  • Combine with Singleton pattern for global access if needed.

  • Avoid making it responsible for business rules — just coordination.


🧭 Conclusion

The Façade Design Pattern acts like a front desk for your codebase — it hides unnecessary complexity and makes client interactions smooth and simple.
When used properly, it makes large systems more maintainable, readable, and user-friendly.


Monday, September 29, 2025

🏭 Factory Design Pattern in C# with Real-Time Example

📌 What is the Factory Design Pattern?

The Factory Design Pattern is a creational pattern used in object-oriented programming to abstract the process of object creation. Instead of instantiating classes directly using new, the Factory Pattern provides a method that returns instances of different classes based on input parameters.

This pattern is especially useful when:

  • The exact type of object to create is determined at runtime.
  • You want to encapsulate object creation logic.
  • You need to adhere to the Open/Closed Principle (open for extension, closed for modification).

🚗 Real-Time Example: Vehicle Factory in C#

Imagine you're building a transportation management system that handles different types of vehicles: Car, Bike, and Truck. Each vehicle has its own behavior, but the client code shouldn't worry about how these objects are created.

✅ Step-by-Step Implementation

1. Define a Common Interface

public interface IVehicle
{
    void Start();
}

2. Create Concrete Implementations

public class Car : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Car started.");
    }
}

public class Bike : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Bike started.");
    }
}

public class Truck : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Truck started.");
    }
}

3. Implement the Factory Class

public static class VehicleFactory
{
    public static IVehicle GetVehicle(string vehicleType)
    {
        switch (vehicleType.ToLower())
        {
            case "car":
                return new Car();
            case "bike":
                return new Bike();
            case "truck":
                return new Truck();
            default:
                throw new ArgumentException("Invalid vehicle type");
        }
    }
}

4. Client Code

class Program
{
    static void Main(string[] args)
    {
        IVehicle vehicle1 = VehicleFactory.GetVehicle("car");
        vehicle1.Start();

        IVehicle vehicle2 = VehicleFactory.GetVehicle("bike");
        vehicle2.Start();
    }
}

🎯 Benefits of Using Factory Pattern in C#

  • Encapsulation: Object creation logic is hidden from the client.
  • Scalability: Easily add new vehicle types without changing client code.
  • Maintainability: Centralized object creation makes debugging and updates easier.
  • Loose Coupling: Promotes interface-based programming.

📝 Final Thoughts

The Factory Design Pattern is a cornerstone of clean, scalable software architecture. Whether you're building enterprise applications or small utilities, this pattern helps you write flexible and maintainable code.


Thursday, September 25, 2025

Write a program to Generate all possible permutations of the string "ABCDEF" using C#.

 Since "ABCDEF" has 6 characters, the number of permutations = 6! = 720.

Here’s a C# program to generate and print them:

using System; using System.Collections.Generic; class Program { static void Main() { string input = "ABCDEF"; var results = new List<string>(); GetPermutations(input.ToCharArray(), 0, results); Console.WriteLine($"Total Permutations: {results.Count}"); foreach (var str in results) { Console.WriteLine(str); } } static void GetPermutations(char[] arr, int index, List<string> results) { if (index == arr.Length - 1) { results.Add(new string(arr)); } else { for (int i = index; i < arr.Length; i++) { Swap(ref arr[index], ref arr[i]); GetPermutations(arr, index + 1, results); Swap(ref arr[index], ref arr[i]); // backtrack } } } static void Swap(ref char a, ref char b) { if (a == b) return; char temp = a; a = b; b = temp; } }

🔹 How it works:

  1. Uses recursion to generate all permutations.

  2. Swaps characters, calls recursively, then backtracks to restore the original order.

  3. Stores all unique permutations in a List<string>.


🔹 Sample Output:

Total Permutations: 720 ABCDEF ABCDE F ABCDFE ABCEDF ... FEDCBA

👉 This prints all 720 unique permutations of "ABCDEF".

Don't Copy

Protected by Copyscape Online Plagiarism Checker