CSharp - Other

BlockingCollection - Improves Multithreaded Performance

BlockingCollection<T> helps in producer-consumer scenarios for thread-safe data sharing.


Before (Manual Locking with Poor Performance)

Manually managing thread synchronization with locks leads to complex and inefficient code.

List<int> data = new List<int>();
object lockObj = new object();


void Producer()
{
    for (int i = 0; i < 5; i++)
    {
        lock (lockObj)
        {
            data.Add(i);
        }
    }
}


void Consumer()
{
    while (true)
    {
        int item;
        lock (lockObj)
        {
            if (data.Count == 0) continue;
            item = data[0];
            data.RemoveAt(0);
        }
        Console.WriteLine($"Consumed {item}");
    }
}


After (Efficient Producer-Consumer with BlockingCollection)

Using BlockingCollection<T>, thread synchronization is simpler and more efficient.

using System.Collections.Concurrent;


BlockingCollection<int> queue = new BlockingCollection<int>();


void Producer()
{
    for (int i = 0; i < 5; i++)
    {
        queue.Add(i);
    }
    queue.CompleteAdding();
}


void Consumer()
{
    foreach (var item in queue.GetConsumingEnumerable())
    {
        Console.WriteLine($"Consumed {item}");
    }
}


Building a Dynamic Predicate Based on Conditions

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}

class Program
{
    static void Main()
    {
        var products = new List<Product>
        {
            new Product { Name = "Laptop", Price = 1000 },
            new Product { Name = "Phone", Price = 700 },
            new Product { Name = "Tablet", Price = 400 }
        };

        string propertyToCheck = "Price";
        int minPrice = 500;

        var parameter = Expression.Parameter(typeof(Product), "p");
        var property = Expression.Property(parameter, propertyToCheck);
        var constant = Expression.Constant(minPrice);
        var condition = Expression.GreaterThan(property, constant);

        var lambda = Expression.Lambda<Func<Product, bool>>(condition, parameter);

        var filteredProducts = products.AsQueryable().Where(lambda).ToList();

        foreach (var product in filteredProducts)
        {
            Console.WriteLine($"{product.Name}, ${product.Price}");
        }
    }
}

C# Error with null-conditional operator and await

You can add ?? Operator so if ?. returns null task use CompletedTask instead.

await (this.MyObject?.MyMethod() ?? Task.CompletedTask)

Calculate Factorial Iteratively

A common task is computing the factorial of a number. This iterative approach keeps the code minimal.

int n = 5;
int factorial = 1;
for (int i = 1; i <= n; i++) factorial *= i;
Console.WriteLine(factorial);


Explanation: A simple for-loop multiplies numbers from 1 to n to compute the factorial, all within just three lines of code.

Calling a method every x minutes

var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromMinutes(5);

var timer = new System.Threading.Timer((e) =>
{
    MyMethod();   
}, null, startTimeSpan, periodTimeSpan);

Cannot add System.Data.Spatial to Domain classes

EF6 this has been renamed to System.Data.Entity.Spatial.

Centralized logging resource usage for all controller actions

.NET Framework


Create a Custom Action Filter

using System;
using System.Diagnostics;
using System.Web.Mvc;


public class ResourceUsageLoggingFilter : ActionFilterAttribute
{
    private Stopwatch _stopwatch;
    private long _startMemory;
    private TimeSpan _startCpuTime;


    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Start measuring CPU and memory
        _stopwatch = Stopwatch.StartNew();
        var process = Process.GetCurrentProcess();
        _startMemory = process.WorkingSet64;
        _startCpuTime = process.TotalProcessorTime;


        base.OnActionExecuting(filterContext);
    }


    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        _stopwatch.Stop();
        var process = Process.GetCurrentProcess();
        var endMemory = process.WorkingSet64;
        var endCpuTime = process.TotalProcessorTime;


        // Calculate memory and CPU usage
        var memoryUsedMb = (endMemory - _startMemory) / (1024 * 1024);
        var cpuUsedMs = (endCpuTime - _startCpuTime).TotalMilliseconds;


        // Log if usage exceeds thresholds
        if (memoryUsedMb > 50 || cpuUsedMs > 100) // Example thresholds
        {
            Debug.WriteLine($"High Resource Usage: Action: {filterContext.ActionDescriptor.ActionName}, " +
                            $"Memory: {memoryUsedMb} MB, CPU: {cpuUsedMs} ms, Duration: {_stopwatch.ElapsedMilliseconds} ms");
        }


        base.OnActionExecuted(filterContext);
    }
}


Register the filter in Global.asax

protected void Application_Start()
{
    GlobalFilters.Filters.Add(new ResourceUsageLoggingFilter());
}


Decorate individual controllers or actions with the filter

[ResourceUsageLoggingFilter]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}


.NET Core


Create Middleware

public class ResourceUsageLoggingMiddleware
{
    private readonly RequestDelegate _next;


    public ResourceUsageLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }


    public async Task InvokeAsync(HttpContext context)
    {
        var process = Process.GetCurrentProcess();
        var startMemory = process.WorkingSet64;
        var startCpuTime = process.TotalProcessorTime;
        var stopwatch = Stopwatch.StartNew();


        await _next(context);


        stopwatch.Stop();
        var endMemory = process.WorkingSet64;
        var endCpuTime = process.TotalProcessorTime;


        var memoryUsedMb = (endMemory - startMemory) / (1024 * 1024);
        var cpuUsedMs = (endCpuTime - startCpuTime).TotalMilliseconds;


        if (memoryUsedMb > 50 || cpuUsedMs > 100) // Example thresholds
        {
            Console.WriteLine($"High Resource Usage: Request: {context.Request.Path}, " +
                              $"Memory: {memoryUsedMb} MB, CPU: {cpuUsedMs} ms, Duration: {stopwatch.ElapsedMilliseconds} ms");
        }
    }
}


Register the middleware in Startup.cs

public void Configure(IApplicationBuilder app)
{
    app.UseMiddleware<ResourceUsageLoggingMiddleware>();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Check if a Number is Prime

Determining if a number is prime can be elegantly solved in one line using LINQ.

int number = 29;
bool isPrime = Enumerable.Range(2, number - 2).All(i => number % i != 0);
Console.WriteLine(isPrime);


Explanation: Enumerable.Range(2, number - 2) generates a sequence from 2 to number - 1. The All method checks that no number in this range divides number evenly, confirming its primality.

Check if a String is a Palindrome

Checking whether a word is a palindrome can be done succinctly with LINQ.

string word = "radar";
bool isPalindrome = word.SequenceEqual(word.Reverse());
Console.WriteLine(isPalindrome);


Explanation: This code compares the original string with its reversed version using SequenceEqual. If they match, the string is a palindrome.

Chunks

Chunks are a way to split a collection into smaller groups or "chunks" of a specific size. This way you can break a long list of items into smaller groups to make it easier to work with.


Our Products list has 12 items. We can break it up into groups of 3 items and handle each chunk in a foreach:

IEnumerable<Product[]> chunks = ProductList.Products.Chunk(3);

foreach (Product[] chunk in chunks)
{
    foreach (Product product in chunk)
    {
        Console.WriteLine(product.Title);
    }
}


Benefits of chunks:

  1. Processing manageable parts is easier than dealing with a huge list.
  2. It manages memory more efficiently.
  3. Each chunk could be processed in parallel, which is a great improvement.
  4. It improves error handling. Errors in a certain chunk don't affect the other chunks. You can handle errors in a chunk, rather than on the whole list.
  5. Testing is made more efficient since you test a specific portion of the dataset.

Cloning an Array

int[] original = { 1, 2, 3, 4, 5 };
int[] cloned = (int[])original.Clone();
// Result: cloned = { 1, 2, 3, 4, 5 }

Common Attributes

[Obsolete] Attribute

Marks a program element as obsolete or deprecated, generating a warning or error when used.

[Obsolete("This method is deprecated, use NewMethod instead.")]
public void OldMethod() { }


[Serializable] Attribute

Indicates that an object can be serialized for storage or transmission.

[Serializable]
public class SerializableObject { }


[DataContract] and [DataMember] Attributes

Used in Windows Communication Foundation (WCF) for specifying serializable classes and members.

[DataContract]
public class Person
{
    [DataMember]
    public string FirstName { get; set; }
}


[DllImport] Attribute

Used for calling functions from unmanaged code.

class Program
{
    [DllImport("user32.dll")]
    public static extern int MessageBox(int hWnd, string text, string caption, int type);
}


[Conditional] Attribute

Specifies that a method should be called conditionally based on compilation symbols.

class Program
{
    [Conditional("DEBUG")]
    public static void DebugMethod()
    {
        // This method will only be included if DEBUG is defined.
    }
}


[ThreadStatic] Attribute

Declares thread-local storage for a field, giving each thread its own copy.

public class ThreadLocalExample
{
    [ThreadStatic]
    public static int threadLocalValue;
}


[Serializable] Attribute

Marks a class as serializable for binary serialization.

[Serializable]
public class SerializableClass { }


[DefaultValue] Attribute

Specifies the default value for a property or field.

public class Example
{
    [DefaultValue(42)]
    public int MyProperty { get; set; }
}


[Description] Attribute

Provides a description for a property, event, or component.

public class Example
{
    [Description("This is a description.")]
    public int MyProperty { get; set; }
}


[DisplayName] Attribute

Specifies a display name for a property or event.

public class Example
{
    [DisplayName("Display Name")]
    public int MyProperty { get; set; }
}


[Browsable] Attribute

Indicates whether a property or event should be displayed in a designer.

public class Example
{
    [Browsable(false)]
    public int MyProperty { get; set; }
}


[NonSerialized] Attribute

Prevents a field from being serialized.

[Serializable]
public class SerializableObject
{
    [NonSerialized]
    public int NonSerializableField;
}


[XmlIgnore] Attribute

Excludes a property from XML serialization.

public class Example
{
    [XmlIgnore]
    public int MyProperty { get; set; }
}


[XmlAttribute] Attribute

Specifies that a property should be serialized as an XML attribute.

public class Person
{
    [XmlAttribute]
    public string FirstName { get; set; }
}


[XmlElement] Attribute

Specifies that a property should be serialized as an XML element.

public class Person
{
    [XmlElement]
    public string FirstName { get; set; }
}


[Serializable] Attribute

Marks a method as a web method that can be called from a web service.

[WebService]
public class MyWebService
{
    [WebMethod]
    public string HelloWorld()
    {
        return "Hello, world!";
    }
}


[Authorize] Attribute

Restricts access to a controller or action method to authorized users.

[Authorize]
public class SecureController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}


[Route] Attribute

Specifies the route template for an action method in ASP.NET Core.

[Route("api/[controller]")]
public class MyController : Controller
{
    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        // Handle GET request
    }
}


[Required] Attribute

Indicates that a property is required for model validation.

public class Person
{
    [Required]
    public string FirstName { get; set; }
}


[MaxLength] Attribute

Specifies the maximum length for a string property.

public class Person
{
    [MaxLength(50)]
    public string FirstName { get; set; }
}


[MinLength] Attribute

Specifies the minimum length for a string property.

public class Person
{
    [MinLength(2)]
    public string FirstName { get; set; }
}


[RegularExpression] Attribute

Defines a regular expression pattern for string validation.

public class Person
{
    [RegularExpression(@"^[A-Za-z]+$")]
    public string FirstName { get; set; }
}


[Key] Attribute

Specifies a primary key for an entity in Entity Framework.

public class Person
{
    [Key]
    public int Id { get; set; }
}


[ForeignKey] Attribute

Indicates a foreign key relationship in Entity Framework.

public class Order
{
    public int CustomerId { get; set; }
    [ForeignKey("CustomerId")]
    public Customer Customer { get; set; }
}


[Table] Attribute

Specifies the table name for an entity in Entity Framework.

[Table("ProductTable")]
public class Product
{
    public int Id { get; set; }
}


[Column] Attribute

Maps a property to a specific database column in Entity Framework.

public class Product
{
    [Column("ProductName")]
    public string Name { get; set; }
}


[StringLength] Attribute

Specifies the maximum and minimum string length for validation.

public class Person
{
    [StringLength(50, MinimumLength = 2)]
    public string FirstName { get; set; }
}


[JsonProperty] Attribute

Maps a property to a specific JSON property name during serialization and deserialization.

public class Person
{
    [JsonProperty("first_name")]
    public string FirstName { get; set; }
}


[JsonIgnore] Attribute

Excludes a property from JSON serialization.

public class Person
{
    [JsonIgnore]
    public string SecretData { get; set; }
}


[AllowedValues] and [DeniedValues] Attributes

AllowedValues restricts a property to specific values, while DeniedValues blocks certain values

public class Product
{
    [AllowedValues("Chocolate", "Candy", "Fruit")]
    [DeniedValues("Vegetable", "Meat")]
    public required string Title { get; set; }
}


[Base64String] Attributes

Ensures that the property contains a valid Base64-encoded string

public class Document
{
    [Base64String]
    public required string EncodedContent { get; set; }
}


[Length] Attributes

Restricts the length of the string between 5 and 50 characters

public class UserProfile
{
    [Length(5, 50)]
    public required string Username { get; set; }
}


[Range] Attributes

Ensures that the date is within the specified range (for DateOnly and TimeOnly types)

public class Event
{
    [Range(typeof(DateOnly), "2024-01-01", "2025-12-31")]
    public required DateOnly EventDate { get; set; }
  
    [Range(typeof(TimeOnly), "08:00:00", "18:00:00")]
    public required TimeOnly EventTime { get; set; }
}


[RequiredIf] Attributes

Makes the property required only if a condition is met (e.g., TrackingNumber is required if IsExpressShipping is true)

public class Order
{
    [RequiredIf(nameof(IsExpressShipping), true)]
    public string? TrackingNumber { get; set; }
  
    public bool IsExpressShipping { get; set; }
}


[UnicodeCharacters] Attributes

Ensures that the string contains only Unicode characters

public class Message
{
    [UnicodeCharacters]
    public required string Content { get; set; }
}


[DisallowNull] Attributes

Prevents the property from being set to null

public class Settings
{
    [DisallowNull]
    public required string ConfigName { get; set; }
}


[DisallowDefault] Attributes

Prevents the property from being set to its default value (e.g., 0 for numeric types)

public class Transaction
{
    [DisallowDefault]
    public required decimal Amount { get; set; }
}


[DataType] Attributes

Specifies that the property should be treated as a specific data type (e.g., Currency and Duration)

public class Payment
{
    [DataType(DataType.Currency)]
    public required decimal TotalPrice { get; set; }
  
    [DataType(DataType.Duration)]
    public required TimeSpan ProcessingTime { get; set; }
}


[Display] Attributes

Enhances display attributes with localization support

public class Product
{
    [Display(Name = "Product Name", Description = "The name of the product", ResourceType = typeof(Resources))]
    public required string Title { get; set; }
}