Introduction
Optimizing performance is critical for delivering responsive Windows applications. This guide outlines proven strategies, tools, and code patterns to help you reduce latency, improve throughput, and lower resource consumption.
Best Practices
- Minimize UI Thread Workload: Offload heavy calculations to background threads using
ThreadPool
or Task.Run
.
- Cache Frequently Used Data: Use
MemoryCache
or in‑memory dictionaries with appropriate expiration policies.
- Leverage Asynchronous I/O: Prefer async APIs (e.g.,
ReadAsync
, WriteAsync
) to avoid blocking threads.
- Reduce Layout Passes: Batch visual changes and use
UIElement.InvalidateMeasure
judiciously.
- Optimize Resource Usage: Dispose of IDisposable objects promptly and avoid unnecessary GDI handles.
Microsoft provides a suite of tools to analyze performance bottlenecks:
Tool | Use Case |
Windows Performance Recorder (WPR) | System‑wide tracing, low‑level kernel events |
Windows Performance Analyzer (WPA) | Visualizing WPR recordings, identifying CPU hotspots |
Visual Studio Profiler | Managed code sampling, instrumentation, memory usage |
PerfView | ETW‑based .NET GC and allocation analysis |
Code Samples
// Example: Asynchronous file read with cancellation support
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
public static async Task<string> ReadFileAsync(string path, CancellationToken token)
{
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true);
using var reader = new StreamReader(stream);
return await reader.ReadToEndAsync().ConfigureAwait(false);
}
// Example: Parallel processing with Parallel.ForEach
using System.Collections.Concurrent;
using System.Threading.Tasks;
var items = new ConcurrentBag<int>(Enumerable.Range(1, 1000));
Parallel.ForEach(items, item =>
{
// Simulate work
var result = Math.Sqrt(item);
});
Troubleshooting
When performance degrades, follow these steps:
- Capture a trace with
wpr -start MyTrace -on Latency
and reproduce the issue.
- Analyze the trace in WPA; look for high CPU usage or long I/O wait times.
- Use the Visual Studio Diagnostic Tools to inspect memory and thread activity.
- Identify hot paths in code, apply async/await or parallelism as needed.
References