Overview
.NET Programming for Performance provides experienced .NET developers with practical knowledge and techniques for improving code intended for live production environments. Through lecture and hands-on labs this course explores three areas that are critical to the success of all applications Memory management, Threads, and Exception management. You'll learn effective practices for avoiding problems as well as learning how to troubleshoot problematic code. Real-world problems can't always be solved by running in the Visual Studio debugger, so you will practice getting memory dumps from live systems and see how to use Visual Studio in concert with tools like WinDBG, SOS, and Performance Monitor to ferret out problems like memory leaks, deadlocks, and runaway threads. You'll return from the week ready to design and build applications that avoid performance traps, scale predictably and gracefully handle "difficult" failures. You'll also have a new understanding of deep debugging techniques that will help you unearth and fix the difficult bugs that inevitably arise in every system.
Day 1
Exception Safety
Proper use of exceptions is the mark of a good code. This module will talk about best practices for exception management with a particular look at the three degrees of exception safety and how to achieve them in .NET.
Unhandled Exceptions
Unhandled exceptions are a fact of life. In this module you will learn how to best deal with unhandled exceptions in general code as well as in ASP.NET and Windows Forms applications. You'll also learn how AppDomainManagers and Enterprise Library can be used to automate exception management for large applications.
Debugging Exceptions
This module examines debugging of exceptions and provides an introduction to using ADPLUS to automatically capture memory dumps for processes failing due to unanticipated exceptions and using WinDBG to figure out just what happened.
Transactions
Transactions offer a number of improvements over traditional exception-based code, especially with the support of the transactional file system and registry in Windows Vista. This module looks at transactional design as an alternative to exceptions with a particular look at how System.Transactions can automate most of the hard work.
Day 2
Async Processing
Performing tasks in the background is a good way to get work done while keeping the UI responsive. Toward that end, this module introduces the IAsyncResult-based pattern that is most commonly used for async invocation in .NET libraries and how to leverage it yourself using async delegate invocation. This model is then contrasted with BackgroundWorker which offers a few additional capabilities for applications desiring this kind of functionality
Thread Safety
Asynchronous programming requires careful attention to detail since most objects are not designed with multithreaded access in mind. This module introduces the importance of Interlocked and Monitor-based synchronization.
Parallel Processing
Many systems rely on using threads to process requests in parallel. This module covers the .NET thread pool and patterns useful for parallel processing. We will examine how the thread pool works, what it's good for and how to control it. We also will look at dangers of deadlock and finish with a look at how to use Trace.CorrelationManager to track requests as they move through your system.
Multithreading
This talk explores the world of custom threads. First we will explore the subtle relationship between managed and native thread, then we will focus on applications that use long-running threads to monitor external stimuli. We'll look at useful patterns like Monitor.Wait / Pulse and discuss how and where to use Win32 synchronization objects like Mutex, EventWaitHandle, and Semaphore.
Day 3
Debugging Threads
Multithreaded applications can have problems ranging from deadlocks to data corruption to runaway threads hogging the CPU. In this module you will learn how to spot problems and how to debug them with Visual Studio, WinDBG, and SOS.
Pluggable Applications
IDisposable may be the most important interface in .NET today. Implementing it can be tricky business, especially when versioning and inheritance gets involved. This module examines how to best approach IDisposable when designing applications that use it.
App Domains
Understanding how to write efficient managed code requires understanding the tradeoffs the .NET Garbage Collector makes when executing code. This module covers the mechanics of the .NET Garbage collection (Generations, the Large Object Heap) and the various ways in which it can be tuned for particular applications.
GC Mechanics
A firm understanding of the Garbage Collector is required when evaluating designs for performance and scalability implications. This talk takes a deep look at the mechanics and motivations of the .NET garbage collector.
Day 4
GC and you
This talk expands on the previous talk to discuss the impact Garbage Collection will have on your code and vice-versa. You'll learn about the "midlife crisis" problem, when to call GC.Collect, when to set variables to null, and how to use classes like WeakReference to write code that works with the garbage collector instead of against it.
Code and Memory
"Use Less Memory" is perhaps the best advice for improving the performance of any Windows application today. There is more to memory usage than objects on the managed heap however. This module looks at how Assemblies, types, and JIT Compilation all contribute to your overall memory usage and shows you how to mitigate problems, including some surprisingly simple techniques that can have some significant consequences.
Debugging Memory Issues
"Why does my application use so much memory? Why is my application leaking memory? Why isn't this object being collected by the garbage collector?" In keeping with the previous debugging modules this module shows how to attack memory-related issues in your code using the familiar tools of Visual Studio and WinDBG. Never again will you be left wondering where all your memory is going.