Memory Leak in a WPF Application
Scenario:
A WPF application's memory usage increases over time, even when idle. The application uses event subscriptions, but events are not unsubscribed. How would you diagnose and resolve this issue?
Answer:
Cause: Event subscribers hold strong references to publishers. If not unsubscribed, publishers outlive subscribers, keeping them in memory.
Diagnosis: Use a memory profiler (e.g., dotMemory, Visual Studio Diagnostic Tools) to inspect object retention graphs. Look for lingering
EventHandlerreferences.Fix:
Unsubscribe events explicitly when no longer needed.
Use weak event patterns (e.g.,
WeakEventManager).
csharp// Before (leaks): publisher.Event += SubscriberMethod; // Fix: publisher.Event -= SubscriberMethod; // Unsubscribe when done // Or use WeakEventManager: WeakEventManager<PublisherType, EventArgs>.AddHandler(publisher, nameof(publisher.Event), SubscriberMethod);
2. Async Deadlock in ASP.NET
Scenario:
An ASP.NET MVC action uses Task.Result to call an async method, causing deadlocks. How would you refactor this?
Answer:
Cause: Blocking on async code (e.g.,
Result/Wait()) in a synchronous context deadlocks due to thread pool exhaustion.Fix: Replace blocking calls with
async/awaitthroughout the call chain.csharp// Before (deadlocks): public ActionResult GetData() { var data = SomeAsyncMethod().Result; return View(data); } // After (async all the way): public async Task<ActionResult> GetData() { var data = await SomeAsyncMethod(); return View(data); }
3. High CPU in Parallel.ForEach
Scenario:
A Parallel.ForEach loop processes a large collection but causes high CPU due to thread contention. How do you optimize it?
Answer:
Cause: Shared resources or fine-grained work items cause excessive locking.
Optimizations:
Use
Partitioner.Createto reduce overhead.Avoid shared state; use thread-local variables (
ThreadLocal<T>).
csharpvar partitioner = Partitioner.Create(data, EnumerablePartitionerOptions.NoBuffering); Parallel.ForEach(partitioner, item => Process(item)); // Or use concurrent collections: var results = new ConcurrentBag<ResultType>(); Parallel.ForEach(data, item => results.Add(Process(item)));
4. Captive Dependency in DI
Scenario:
A singleton service in ASP.NET Core injects a scoped service, causing the scoped instance to behave like a singleton. How do you fix this?
Answer:
Cause: Scoped services injected into singletons become captive, as their lifespan is extended.
Fix: Use
IServiceScopeFactoryto resolve scoped services within the singleton.csharppublic class SingletonService { private readonly IServiceScopeFactory _scopeFactory; public SingletonService(IServiceScopeFactory scopeFactory) => _scopeFactory = scopeFactory; public void Method() { using var scope = _scopeFactory.CreateScope(); var scopedService = scope.ServiceProvider.GetRequiredService<IScopedService>(); scopedService.DoWork(); } }
5. Optimizing Slow LINQ Queries on Large Data
Scenario:
A LINQ-to-Objects query on a 1-million-item collection is slow. How would you optimize it?
Answer:
Optimizations:
Use PLINQ (
AsParallel()) for CPU-bound work.Replace
classwithstructand useSpan<T>to reduce heap allocations.
csharp// PLINQ example: var results = data.AsParallel() .Where(item => item.IsValid) .Select(item => Transform(item)) .ToList(); // Span<T> example (for stack-based processing): Span<DataItem> span = dataArray.AsSpan(); foreach (ref var item in span) { Process(ref item); // Avoids boxing and heap allocations }
6. Secure Password Handling
Scenario:
How would you securely hash passwords in a .NET application to prevent exposure if the database is compromised?
Answer:
Best Practice: Use
Rfc2898DeriveBytes(PBKDF2) with a high iteration count.csharppublic string HashPassword(string password) { byte[] salt = new byte[16]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(salt); } var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100000, HashAlgorithmName.SHA256); byte[] hash = pbkdf2.GetBytes(32); return Convert.ToBase64String(salt) + ":" + Convert.ToBase64String(hash); }
No comments:
Post a Comment