Table of Contents v
8 Methods 187
Instance Constructors and Classes (Reference Types) 187
Instance Constructors and Structures (Value Types)
191
Type Constructors
194
Type Constructor Performance
198
Operator Overload Methods
200
Operators and Programming Language Interoperability
203
Conversion Operator Methods
204
Extension Methods
207
Rules and Guidelines
210
Extending Various Types with Extension Methods
211
The Extension Attribute
213
Partial Methods
213
Rules and Guidelines
216
9 Parameters 219
Optional and Named Parameters 219
Rules and Guidelines
220
The
DefaultParameterValue and Optional Attributes 222
Implicitly Typed Local Variables
223
Passing Parameters by Reference to a Method
225
Passing a Variable Number of Arguments to a Method
231
Parameter and Return Type Guidelines
233
Const-ness 235
10 Properties 237
Parameterless Properties 237
Automatically Implemented Properties
241
Defining Properties Intelligently
242
Object and Collection Initializers
245
Anonymous Types
247
The
System.Tuple Type 250
Parameterful Properties
252
The Performance of Calling Property Accessor Methods
257
Property Accessor Accessibility
258
Generic Property Accessor Methods
258
11 Events 259
Designing a Type That Exposes an Event 260
Step #1: Define a type that will hold any additional information
that should be sent to receivers of the event notification
261
Step #2: Define the event member
262
Step #3: Define a method responsible for raising the event to
notify registered objects that the event has occurred
263
Step #4: Define a method that translates the input into the desired event
266
How the Compiler Implements an Event
266
vi Table of Contents
Designing a Type That Listens for an Event 269
Explicitly Implementing an Event
271
12 Generics 275
Generics in the Framework Class Library 280
Wintellect’s Power Collections Library
281
Generics Infrastructure
282
Open and Closed Types
283
Generic Types and Inheritance
285
Generic Type Identity
287
Code Explosion
288
Generic Interfaces
289
Generic Delegates
290
Delegate and Interface Contravariant and Covariant Generic Type Arguments
291
Generic Methods
293
Generic Methods and Type Inference
294
Generics and Other Members
296
Verifiability and Constraints
296
Primary Constraints
299
Secondary Constraints
300
Constructor Constraints
301
Other Verifiability Issues
302
13 Interfaces 307
Class and Interface Inheritance 308
Defining an Interface
308
Inheriting an Interface
310
More About Calling Interface Methods
312
Implicit and Explicit Interface Method Implementations (What’s Happening
Behind the Scenes)
314
Generic Interfaces
315
Generics and Interface Constraints
318
Implementing Multiple Interfaces That Have the Same Method Name
and Signature
319
Improving Compile-Time Type Safety with Explicit Interface Method
Implementations
320
Be Careful with Explicit Interface Method Implementations
322
Design: Base Class or Interface?
325
Part III Essential Types
14 Chars, Strings, and Working with Text 327
Characters 327
The
System.String Type 330
Constructing Strings
330
Strings Are Immutable
333
Comparing Strings
334
Table of Contents vii
String Interning 340
String Pooling
343
Examining a String’s Characters and Text Elements
343
Other String Operations
346
Constructing a String Efficiently
346
Constructing a
StringBuilder Object 347
StringBuilder Members 348
Obtaining a String Representation of an Object:
ToString 350
Specific Formats and Cultures 351
Formatting Multiple Objects into a Single String
355
Providing Your Own Custom Formatter
356
Parsing a String to Obtain an Object:
Parse 359
Encodings: Converting Between Characters and Bytes 361
Encoding and Decoding Streams of Characters and Bytes
367
Base-64 String Encoding and Decoding
368
Secure Strings
369
15 Enumerated Types and Bit Flags 373
Enumerated Types 373
Bit Flags
379
Adding Methods to Enumerated Types
383
16 Arrays 385
Initializing Array Elements 388
Casting Arrays
390
All Arrays Are Implicitly Derived from
System.Array 392
All Arrays Implicitly Implement
IEnumerable, ICollection, and IList 393
Passing and Returning Arrays
394
Creating Non-Zero–Lower Bound Arrays
395
Array Access Performance
396
Unsafe Array Access and Fixed-Size Array
401
17 Delegates 405
A First Look at Delegates 405
Using Delegates to Call Back Static Methods
408
Using Delegates to Call Back Instance Methods
409
Demystifying Delegates
410
Using Delegates to Call Back Many Methods (Chaining)
415
C#’s Support for Delegate Chains
419
Having More Control over Delegate Chain Invocation
419
Enough with the Delegate Definitions Already (Generic Delegates)
422
C#’s Syntactical Sugar for Delegates
423
Syntactical Shortcut #1: No Need to Construct a Delegate Object
424
Syntactical Shortcut #2: No Need to Define a Callback Method
424
Syntactical Shortcut #3: No Need to Wrap Local Variables in a Class
Manually to Pass Them to a Callback Method
428
Delegates and Reflection
431
viii Table of Contents
18 Custom Attributes 435
Using Custom Attributes 435
Defining Your Own Attribute Class
439
Attribute Constructor and Field/Property Data Types
443
Detecting the Use of a Custom Attribute
444
Matching Two Attribute Instances Against Each Other
448
Detecting the Use of a Custom Attribute Without Creating Attribute-Derived
Objects
451
Conditional Attribute Classes
454
19 Nullable Value Types 457
C#’s Support for Nullable Value Types 459
C#’s Null-Coalescing Operator
462
The CLR Has Special Support for Nullable Value Types
463
Boxing Nullable Value Types
463
Unboxing Nullable Value Types
463
Calling
GetType via a Nullable Value Type 464
Calling Interface Methods via a Nullable Value Type
464
Part IV Core Facilities
20 Exceptions and State Management 465
Defining “Exception” 466
Exception-Handling Mechanics
467
The
try Block 468
The
catch Block 469
The
finally Block 470
The
System.Exception Class 474
FCL-Defined Exception Classes
478
Throwing an Exception
480
Defining Your Own Exception Class
481
Trading Reliability for Productivity
484
Guidelines and Best Practices
492
Use
finally Blocks Liberally 492
Don’t
Catch Everything 494
Recovering Gracefully from an Exception
495
Backing Out of a Partially Completed Operation When an Unrecoverable
Exception Occurs—Maintaining State
496
Hiding an Implementation Detail to Maintain a “Contract”
497
Unhandled Exceptions
500
Debugging Exceptions
504
Exception-Handling Performance Considerations
506
Constrained Execution Regions (CERs)
509
Code Contracts
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .512
Table of Contents ix
21 Automatic Memory Management (Garbage Collection) 519
Understanding the Basics of Working in a Garbage-Collected Platform 520
Allocating Resources from the Managed Heap
521
The Garbage Collection Algorithm
523
Garbage Collections and Debugging
527
Using Finalization to Release Native Resources
530
Guaranteed Finalization Using
CriticalFinalizerObject Types 532
Interoperating with Unmanaged Code by Using
SafeHandle Types 535
Using Finalization with Managed Resources
537
What Causes
Finalize Methods to Be Called? 540
Finalization Internals
541
The Dispose Pattern: Forcing an Object to Clean Up
544
Using a Type That Implements the Dispose Pattern
548
C#’s
using Statement 551
An Interesting Dependency Issue
554
Monitoring and Controlling the Lifetime of Objects Manually
555
Resurrection
566
Generations
568
Other Garbage Collection Features for Use with Native Resources
574
Predicting the Success of an Operation that Requires a Lot of Memory
578
Programmatic Control of the Garbage Collector
580
Thread Hijacking
583
Garbage Collection Modes
585
Large Objects
588
Monitoring Garbage Collections
589
22 CLR Hosting and AppDomains 591
CLR Hosting 592
AppDomains
594
Accessing Objects Across AppDomain Boundaries
597
AppDomain Unloading
609
AppDomain Monitoring
610
AppDomain First-Chance Exception Notifications
612
How Hosts Use AppDomains
612
Executable Applications
612
Microsoft Silverlight Rich Internet Applications
613
Microsoft ASP.NET Web Forms and XML Web Services Applications 613
Microsoft SQL Server
614
Your Own Imagination
614
Advanced Host Control
615
Managing the CLR by Using Managed Code
615
Writing a Robust Host Application
616
How a Host Gets Its Thread Back
617
x Table of Contents
23 Assembly Loading and Reflection 621
Assembly Loading 621
Using Reflection to Build a Dynamically Extensible Application
. . . . . . . . . . . . . . . . . . .626
Reflection Performance
627
Discovering Types Defined in an Assembly
628
What Exactly Is a Type Object?
628
Building a Hierarchy of Exception-Derived Types
631
Constructing an Instance of a Type
632
Designing an Application That Supports Add-Ins
634
Using Reflection to Discover a Type’s Members
637
Discovering a Type’s Members
638
BindingFlags: Filtering the Kinds of Members That Are Returned 643
Discovering a Type’s Interfaces
644
Invoking a Type’s Members
646
Bind Once, Invoke Multiple Times
650
Using Binding Handles to Reduce Your Process’s Memory Consumption
658
24 Runtime Serialization 661
Serialization/Deserialization Quick Start 662
Making a Type Serializable
667
Controlling Serialization and Deserialization
668
How Formatters Serialize Type Instances
672
Controlling the Serialized/Deserialized Data
673
How to Define a Type That Implements
ISerializable when the Base
Type Doesn’t Implement This Interface
678
Streaming Contexts
680
Serializing a Type as a Different Type and Deserializing an Object as a
Different Object
682
Serialization Surrogates
684
Surrogate Selector Chains
688
Overriding the Assembly and/or Type When Deserializing an Object
689
Part V Threading
25 Thread Basics 691
Why Does Windows Support Threads? 691
Thread Overhead
692
Stop the Madness
696
CPU Trends
699
NUMA Architecture Machines
700
CLR Threads and Windows Threads
703
Using a Dedicated Thread to Perform an Asynchronous Compute-Bound
Operation
704
Reasons to Use Threads
706
Thread Scheduling and Priorities
708
Foreground Threads versus Background Threads
713
What Now?
715
Table of Contents xi
26 Compute-Bound Asynchronous Operations 717
Introducing the CLR’s Thread Pool 718
Performing a Simple Compute-Bound Operation
719
Execution Contexts
721
Cooperative Cancellation
722
Tasks
726
Waiting for a Task to Complete and Getting Its Result
727
Cancelling a Task
729
Starting a New Task Automatically When Another Task Completes
731
A Task May Start Child Tasks
733
Inside a Task
733
Task Factories
735
Task Schedulers
737
Parallel’s Static For, ForEach, and Invoke Methods 739
Parallel Language Integrated Query
743
Performing a Periodic Compute-Bound Operation
747
So Many Timers, So Little Time
749
How the Thread Pool Manages Its Threads
750
Setting Thread Pool Limits
750
How Worker Threads Are Managed
751
Cache Lines and False Sharing
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .752
27 I/O-Bound Asynchronous Operations 755
How Windows Performs I/O Operations 755
The CLR’s Asynchronous Programming Model (APM)
761
The
AsyncEnumerator Class 765
The APM and Exceptions
769
Applications and Their Threading Models
770
Implementing a Server Asynchronously
773
The APM and Compute-Bound Operations
774
APM Considerations
776
Using the APM Without the Thread Pool
776
Always Call the
EndXxx Method, and Call It Only Once 777
Always Use the Same Object When Calling the
EndXxx Method 778
Using
ref, out, and params Arguments with BeginXxx and
EndXxx Methods 778
You Can’t Cancel an Asynchronous I/O-Bound Operation
778
Memory Consumption
778
Some I/O Operations Must Be Done Synchronously
779
FileStream-Specific Issues 780
I/O Request Priorities
780
Converting the
IAsyncResult APM to a Task 783
The Event-Based Asynchronous Pattern
784
Converting the EAP to a
Task 786
Comparing the APM and the EAP
788
Programming Model Soup
788
xii Table of Contents
28 Primitive Thread Synchronization Constructs 791
Class Libraries and Thread Safety 793
Primitive User-Mode and Kernel-Mode Constructs
794
User-Mode Constructs
796
Volatile Constructs
797
Interlocked Constructs
803
Implementing a Simple Spin Lock
807
The Interlocked Anything Pattern
811
Kernel-Mode Constructs
813
Event Constructs
817
Semaphore Constructs
819
Mutex Constructs
820
Calling a Method When a Single Kernel Construct Becomes Available
822
29 Hybrid Thread Synchronization Constructs 825
A Simple Hybrid Lock 826
Spinning, Thread Ownership, and Recursion
827
A Potpourri of Hybrid Constructs
829
The
ManualResetEventSlim and SemaphoreSlim Classes 830
The
Monitor Class and Sync Blocks 830
The
ReaderWriterLockSlim Class 836
The
OneManyLock Class 838
The
CountdownEvent Class 841
The
Barrier Class 841
Thread Synchronization Construct Summary
842
The Famous Double-Check Locking Technique
844
The Condition Variable Pattern
848
Using Collections to Avoid Holding a Lock for a Long Time
851
The Concurrent Collection Classes
856
Index 861
Microsoft is interested in hearing your feedback so we can continually improve our books and learning
resources for you. To participate in a brief online survey, please visit:
www.microsoft.com/learning/booksurvey/
What do you think of this book? We want to hear from you!
xiii
Foreword
At first, when Jeff asked me to write the foreword for his book, I was so flattered! He must
really respect me, I thought. Ladies, this is a common thought process error—trust me, he
doesn’t respect you. It turns out that I was about #14 on his list of potential foreword writ-
ers and he had to settle for me. Apparently, none of the other candidates (Bill Gates, Steve
Ballmer, Catherine Zeta-Jones, . . .) were that into him. At least he bought me dinner.
But no one can tell you more about this book than I can. I mean, Catherine could give you a
mobile makeover, but I know all kinds of stuff about reflection and exceptions and C# lan-
guage updates because he has been talking on and on about it for years. This is standard
dinner conversation in our house! Other people talk about the weather or stuff they heard at
the water cooler, but we talk about .NET. Even Aidan, our six-year-old, asks questions about
Jeff’s book. Mostly about when he will be done writing it so they can play something “cool.”
Grant (age 2) doesn’t talk yet, but his first word will probably be “Sequential.”
In fact, if you want to know how this all started, it goes something like this. About 10 years
ago, Jeff went to a “Secret Summit” at Microsoft. They pulled in a bunch of industry experts
(Really, how do you get this title? Believe me, this isn’t Jeff’s college degree), and unveiled
the new COM. Late that night in bed (in our house, this is what we discuss in bed), he talked
about how COM is dead. And he was enchanted. Lovestruck, actually. In a matter of days
he was hanging around the halls of Building 42 on Microsoft’s Redmond campus, hoping to
learn more about this wonderful .NET. The affair hasn’t ended, and this book is what he has
to show for it.
For years, Jeff has told me about threading. He really likes this topic. One time, in New
Orleans, we went on a two-hour walk, alone, holding hands, and he spoke the whole time
about how he had enough content for a threading book: The art of threading. How misun-
derstood threading in Windows is. It breaks his heart, all those threads out there. Where do
they all go? Why were they created if no one had a plan for them? These are the questions of
the universe to Jeff, the deeper meanings in life. Finally, in this book, he has written it down.
It is all here. Believe me folks, if you want to know about threading, no one has thought
about it more or worked with it more than Jeff has. And all those wasted hours of his life (he
can’t get them back) are here at your disposal. Please read it. Then send him an e-mail about
how that information changed your life. Otherwise, he is just another tragic literary figure
whose life ended without meaning or fulfillment. He will drink himself to death on diet soda.
This edition of the book even includes a new chapter about the runtime serializer. Turns out,
this is not a new breakfast food for kids. When I figured out it was more computer talk and
not something to put on my grocery list, I tuned it out. So I don’t know what it says, but it is
in here and you should read it (with a glass of milk).
xiv Foreword
My hope is that now he is finished talking about garbage collection in theory and can get on
with actually collecting our garbage and putting it on the curb. Seriously people, how hard is
that?
Folks, here is the clincher—this is Jeffrey Richter’s magnum opus. This is it. There will be no
more books. Of course, we say this every time he finishes one, but this time we really mean
it. So, 13 books (give or take) later, this is the best and the last. Get it fast, because there are
only a limited number and once they are gone—poof. No more. Just like QVC or something.
Back to real life for us, where we can discuss the important things, like what the kids broke
today and whose turn is it to change the diapers.
Kristin Trace (Jeffrey’s wife)
November 24, 2009
A typical family breakfast at the Richter household
Không có nhận xét nào:
Đăng nhận xét