Errata

CLR via C#

Errata for CLR via C#

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed
Page 7
Paragraph above Figure 1-3

After going to press, the Visual Studio team made a change to new project defaults. When you create a new EXE project, the default platform is x86 (not anycpu). This change was made for many reasons: support for edit & continue, support for IntelliTrace debugging, and allows 32-bit COM components to work correctly when interoperating with them. And, since most applications do not need a 64-bit address space, making the default x86 seems like a reasonable solution (for now). New DLL projects default to a platform of anycpu.

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed
Page 19
Last pargraph, last sentense

"Also, note that Ngen'd images cannot be shared across AppDomains,..." is not correct because that limitation had been removed after NGen version 2.0. Please refer following documentation: http://msdn.microsoft.com/en-us/library/6t9t5wcf.aspx.

Note from the Author or Editor:
Yes, you are correct.

Anonymous  Mar 22, 2010  Jul 08, 2011
Printed, PDF, , Other Digital Version
Page 33
Paragraph 1; Line 7

The sentence reads:
"Whereas Windows security is based on a user's identity, code access security is based on permissions that host applications that loading components can control."

I'm not sure, is this meant to say something along the lines of this?
"...permissions that host applications, which are loading components, can control."

Note from the Author or Editor:
Here is the proper text: "Whereas Windows security is based on a user's identity, code access security allows hosts to set permissions thereby controlling what the loaded components can do."

Daniel Fortunov  Sep 27, 2010  Jul 08, 2011
Printed
Page 48
Second note, first pargraph

A value 0x26 of CorTokenType is FileDef (or File) not FileRef.

Note from the Author or Editor:

Fixed in digital version. Will be fixed in the next printed version.

Anonymous  Mar 22, 2010  Jul 19, 2011
Printed
Page 73
3rd paragraph

Microsoft moved the location of the .NET 4.0 GAC. The GAC is in the C:\Windows\Assembly directory for .NET 3.5 and earlier. For .NET 4.0, the directory is C:\Windows\Microsoft.NET\Assembly.

Jeffrey Richter
 
Mar 08, 2010  Jul 08, 2011
Printed, PDF, , Other Digital Version
Page 76
Last Paragraph

The text of first line says "Signing an assembly with a private key ensures that the holder of the corresponding public key produced the assembly." I think it should instead read "Signing an assembly with a private key ensures that the holder of the corresponding public key can consume the assembly."

Note from the Author or Editor:
Yes, your sentence is better but I actually don't like either sentence now because the public key can be held by anyone and everyone. Really, signing an assembly with a private key prevents unauthorized tampering of the assembly's bits.

Siva Chinta  Apr 13, 2011 
Printed
Page 82
Second bullet list item

Manifest table which identifying files in the assembly is "FileDef" table, not "FileRef" table.

Anonymous  Apr 04, 2010  Jul 08, 2011
Printed, PDF,
Page 89
Last paragraph (before last "Important" block)

An erratum in the following sentence:

"This element can be placed as a a child element of the
<assemblyBinding> element in the application's configuration file so
that it applies to all assemblies, or as a child elemtnt of the
<dependantAssembly> element in the application's configuration file to
have it apply to a specific assembly."

Should be <dependentAssembly> element rather than
<dependantAssembly>.

artnib  Aug 30, 2010  Jul 08, 2011
Printed
Page 97
Line 2 of note

There is not "Conversion Operator Methods" section in Chapter 9, "Parameters" but in Chapter 8, "Methods."

Anonymous  Apr 10, 2010  Jul 08, 2011
110
Method name GenProgressReport in figures does not match GetProgressReport in text

Figures 4-6 through 4-13 on pages 105 through 111 use GenProgressReport as the virtual method name from Employee both inside the M3 method and in the type object diagram but the text refers to the virtual method as GetProgressReport. It's pretty easy to figure out but I'll list them below just to be complete.

page 104: Classes Employee and Manager use GetProgressReport
page 105: Figure 4-6 uses GenProgressReport
page 106: Figure 4-7 uses GenProgressReport
GetProgressReport is used in the last two sentences in the 1st paragraph,
page 107: Figure 4-8 uses GenProgressReport
page 108: Figure 4-9 uses GenProgressReport
page 109: Figure 4-10 uses GenProgressReport
Figure 4-11 uses GenProgressReport
page 110: Figure 4-12 uses GenProgressReport
Figure 4-12's caption uses GetProgressReport
1st sentence, 1st paragraph uses GetProgressReport
penultimate sentence, 1st paragraph uses GetProgressReport
last sentence, 2nd paragraph uses GetProgressReport
page 111: Figure 4-13 uses GenProgressReport

BTW, I'm thrilled this is on Safari - I don't have room on my desk for a big clunky book.

ScL

Note from the Author or Editor:
Yes, GenProgressReport should be GetProgress report in all these places.

Steve Lasley  Feb 07, 2010  Jul 08, 2011
Printed
Page 149
First code

"Private" on head of code is supposed to be "internal (or private)."

Note from the Author or Editor:
Yes, I agree.

Anonymous  Mar 22, 2010  Jul 08, 2011
150
Chaper 5, The Dynamic Primitive Type


The below excerpt seems to be inconistent with regard to the explanation of how the System.Runtime.CompilerServices.DynamicAttribute applies to dynamic local variables - see the *** markings in the text below.

"
When the type of a field, method parameter, method return type, or ***local variable***, is specifed as dynamic, the compiler converts this type to the System. Object type and applies an
instance of System.Runtime.CompilerServices.DynamicAttribute to the field, parameter, or return type in metadata.

If a ***local variable*** is specifed as dynamic, then the variable's
type will also be of type Object, but the DynamicAttribute is not applied to the local variable since its usage is self-contained within the method.
"

The first sentence says that System.Runtime.CompilerServices.DynamicAttribute will be applied to dynamic local variable but the second sentence says something different.



Note from the Author or Editor:
Yes, you are correct - local variables cannot have attributes assigned to them.

Anonymous  Feb 19, 2010 
Printed, PDF,
Page 150
listing 1 (after 4th paragraph)

dynamic d1 = 123; //OK: Implicit cast from Int32 to dynamic (boxing)
Int32 n3 = d; //OK: Implicit cast from dynamic to Int32 (unboxing)

The last line should be as follows:

Int32 n2 = d1;

because there is no variable d defined earlier.

Note from the Author or Editor:
Fixed in digital version. Will be fixed in the next printed version.

artnib  Sep 14, 2010  Jul 19, 2011
Printed, PDF, , Other Digital Version
Page 151
First paragraph

If the M method invoked at runtime has a return type of void, an exception is thrown.

Note from the Author or Editor:
Yes, you are right. A RuntimeBinderException is thrown with the following message: "Cannot implicitly convert type 'void' to 'object'"

Anonymous  Sep 10, 2011 
Printed, PDF,
Page 152
Near middle of page

"storing the Int32 result in a local variable (result):"

The result type is Boolean, rather than Int32.

Daniel Fortunov  Oct 04, 2010  Jul 08, 2011
Printed, PDF,
Page 152
Code listing on the bottom half of the page

Whitespaces are missing after the 'new' keyword. Instead of "newType[]" and "newObject[]" it should be "new Type[]" and "new Object[]" respectively.

Yuriy Guts  Jan 25, 2012 
Printed
Page 160
"Important" column

StrongNameIdentityPermission does not work because
1) After .NET 2.0, StrongNameIdentityPermission is not checked for fully trusted assembly, so applications which installed locally or executed from network file sharing can use features which are marked with StrongNameIdentityPermissionAttribute.
2) LinkDemand is no longer supported in .NET 4 Code Access Security model. So this mechanism has not been work at all.

Anonymous  May 15, 2010 
Printed, PDF,
Page 197
First Sentence

Minor Grammar: "Such a call isn't necessary because none of a type's static fields *is* shared or inherited..." should be "...none of a type's static fields *are* shared or inherited..."

Daniel Fortunov  Oct 09, 2010  Jul 08, 2011
Printed
Page 202
Row 13 of Table 8-2

"Suggested CLS-Compliant Method Name" for oeprator '!=' is supposed to be "Equals", not "Compare."

Anonymous  May 15, 2010  Jul 08, 2011
Printed
Page 212
Middle of page

It is written that "You can define extension methods for delegate types, too. For an example of this, turn to page 278 in Chapter 11, 'Events'." However, this sentence is not correct: (1) In the first place, page 278 is not Chapter 11 but Chapter 12 "Generics"; (2) While there is an example of event-related extension methods in page 265 (I think it is cool!), it is extensions method for EventArgs derived classes, not for delegate type. Where is an example of extension method for delegate?

Note from the Author or Editor:
Ah, yes you are right -- this got messed up. The short story is that the reference on page 212 should be removed as there isn't an example that shows an extension method working on a delegate. Although this is a legal thing to do and I should show an example of this.

The long story is that the event-related extension mention in the generics used to extend EventHandler (a delegate). But then, I changed this example to extend EventArgs instead and I forgot about the reference on page 212.

Anonymous  Mar 22, 2010  Jul 19, 2011
Printed
Page 219
Cpde at bottom of page

In the declaration of the M method, spaces are missing between DateTime/dt and Guid/guid.

Jeffrey Richter
 
Apr 11, 2010  Jul 08, 2011
Printed, PDF,
Page 242
2nd Last Line

"A property may be read-only or write-only; field access is always readable and writeable."

A field that is marked `readonly` is only writeable within a constructor.

Daniel Fortunov  Oct 09, 2010 
Printed, PDF, , Other Digital Version
Page 250
1

On page 250, in the last line of the code sampe it has wroten: private TRestm_Rest; It should be replaced with: private TRest m_Rest; (typo - the space is missed).

Yuriy  Sep 30, 2010  Jul 08, 2011
Printed
Page 251
Bottommost code fragment

There should be a space between "var" and "minmax" on this line:
var minmax = MinMax(6, 2);

Jeffrey Richter
 
Apr 13, 2010  Jul 08, 2011
Printed, PDF, , Other Digital Version
Page 251
First line

The parameter of constructor - TRest t - doesn't match with assignment operation in the body of constructor - m_Rest = rest.

Yuriy  Sep 30, 2010 
Printed, PDF,
Page 251-252
MinMax method listings

Missing space between the return type parameter and the name of the MinMax method in two code listings.

Daniel Fortunov  Oct 10, 2010 
Printed, PDF,
Page 263
code sample at the bottom

EventHandler<EventArgs> temp = ...

should read (as on following page 264):

EventHandler<NewMailEventArgs> temp = ...

Michael Ludwig  Jun 27, 2012 
Printed
Page 264
// Version 2,3,4

protected void OnNewMail(NewMailEventArgs e) {

should be:

protected virtual void OnNewMail(NewMailEventArgs e) {

skyiv  Oct 20, 2010  Jul 08, 2011
Printed
Page 277
1st bullet list

I agree that it is not subject for this book, but Java's generics actually does not require that source code is available from its user.

Anonymous  May 23, 2010 
Printed
Page 288
line 7 of code

'DateTimeList' in the comment should be 'dtl'.

Anonymous  May 23, 2010  Jul 08, 2011
Printed, PDF,
Page 288
2nd code example

var dtl = List<DateTime>();

should read

var dtl = new List<DateTime>();

Alastair Hails  Sep 01, 2010  Jul 08, 2011
Printed, PDF
Page 292
Last Paragraph

It Says:

Like delegates, an interface with generic type parameters can have its type parameters be contravariant or covariant. Here is an example of an interface with a contravariant generic type parameter:

public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}

Since T is contravariant, it is possible to have the following code compile and run >successfully:

// This method accepts an IEnumerable of any reference type
Int32 Count(IEnumerable<Object> collection) { ... }
...
// The call below passes an IEnumerable<String> to Count
Int32 c = Count(new[] { "Grant" });


It Should Be:

Either the wording of contravariant needs to change to covariance or the IEnumerator<out T> needs to change to "in" and the example adjusted.

Note from the Author or Editor:
Yes, in the book, I have reversed the terms occasionally by mistake. For the record, out=covariant and in=contravariant.

Chris Greeno  Jul 27, 2010 
Printed
Page 309
Line 4

According to ECMA-335, defining static members on interface is not compliant with CLS (Common Language Specification), but it is part of CLI (Common Language Infrastructure). So "Common Language Infrastructure (CLI)-compliant interface" should be "Common Language Specification (CLS)-compliant interface."

Anonymous  May 29, 2010  Jul 08, 2011
Printed, PDF,
Page 312
Third Example

Please correct my English.

Sean Griffiths has written the errata, I think he made the mistake.
He wrote : "b.Dispose(); does not call the Base's Dispose(), it calls the Derived's Dispose()"
I think the book is right explain that :
b.Dispose(); // Calls Dispose by using b's type: "Base's Dispose"
because if we look to IL code, we can get clear that b.Dispose() indeed call the "Base's Dispose". Here's the snippet of the IL Code, you can examine it using ILDasm or Reflector :

C# Code :
// Calls Dispose by using b's type: "Base's Dispose"
b.Dispose();
// Calls Dispose by using b's object's type: "Derived's Dispose"
((IDisposable)b).Dispose();

IL Code:
L_0030: callvirt instance void CLRviaCSharp.Base::Dispose()
L_0035: nop
L_0036: ldloc.0
L_0037: callvirt instance void [mscorlib]System.IDisposable::Dispose()


Note from the Author or Editor:
Yes, page 312 is correct as is.

adaapanya  Mar 09, 2011  Jul 08, 2011
Printed, PDF,
Page 319
3rd paragraph

the book said ".., and therefore, calling an interface method on a value type always causes boxing."

this is wrong I think, if a value type implement a interface method, calling this method on an instance of the value type won't cause the instance of the value type to be boxed.

Thanks

Leon Zhu  Oct 26, 2010 
Printed, PDF,
Page 326
line -3

non-generic IComparable's Compare

should be:

non-generic IComparer's Compare

skyiv  Oct 31, 2010  Jul 08, 2011
Printed
Page 328
4th and 5th sentence of 3rd paragraph

(1)
ConvertFromUtf32 actually produces a string consisting of ONE OR TWO UTF-16 characters from a single UTF-32 character since some UTF-32 code point is represented ideally with UTF-16 (e.x. ASCII characters). Please refer <http://msdn.microsoft.com/library/en-us/System.Char.ConvertFromUtf32>.
(2)
ConvertToUtf32 produces a 'UTF-32' character from a UTF-16 surrogate pair, not UTF-16.

YFujiwara  Jun 12, 2010 
Printed, PDF,
Page 356
2nd paragraph

3rd line "Obviously, Format calls each object's IFormattableToString method...", actually no object has such a IFormattableToString method, instead we should say each object's IFormattable.ToString() method

Leon Zhu  Nov 14, 2010  Jul 08, 2011
Printed, PDF,
Page 365
Last sentence of 3rd paragraph

number of characters or number of bytes
should be:
number of bytes or number of characters

skyiv  Nov 03, 2010  Jul 08, 2011
Printed, PDF,
Page 365
Line 3

To convert an array of bytes to an array of characters,
should be:
To convert an array of bytes to an array of characters or to a string,

skyiv  Nov 03, 2010  Jul 08, 2011
Printed
Page 391
Last sentense of 3rd bullet

"If every object in the Object[] implements IFormattable[]" should be " If every object in the Object[] implements IFormattable" since each element must be IFormattable in this case.

YFujiwara  Jun 19, 2010  Jul 08, 2011
Printed, PDF,
Page 401
1st paragraph

the first line said, "... is about as fast as the safe two-dimensional array access technique..."

actually, it should say ".. is about as fast as the safe jagged array access technique ...", actually the result on my machine are as follows,


00:00:13.5779201: Safe2DimArrayAccess
00:00:07.5597660: SafeJaggedArrayAccess
00:00:06.3206468: Unsafe2DimArrayAccess

Leon Zhu  Nov 30, 2010  Jul 08, 2011
Printed
Page 403
5th bullet

'Int16' and 'UInt16' are missing from a list of valid fixed array element types.

YFujiwara  Jun 19, 2010  Jul 08, 2011
PDF
Page 457
3rd paragraph

"To understand how they work, we first need to look at the System.Nullable<T> class, which is
defined in the FCL."

System.Nullable<T> is actually defined as a struct not a class.

John Triantafyllopoulos  Jul 17, 2010  Jul 08, 2011
Printed
Page 460
1st bullet item

+++ should be ++,+

Zhou Jing  Jun 24, 2010  Jul 08, 2011
Printed, PDF,
Page 482
Method "Equals" in code sample (class Exception<TExceptionArgs>)

Not actually an error in the text, but a bug in the code. The Equals method defined in Exception<TExceptionArgs> might throw a System.NullReferenceException if obj happens not to be of type Exception<TExceptionArgs>. (Line 3 in the method body: "other.m_args" will raise the exception.)

The author probably meant to write "if (other == null) return false;" instead of "if (obj == null) return false;" (line 2 in the method body), which would prevent the NullReferenceException from occurring.

Regards
Andreas

Btw. The bug is also present in the downloadable source files:
Ch20-1-ExceptionHandling.cs, line 172/173.

andreasfrischknecht  Mar 23, 2011  Jul 08, 2011
Printed
Page 483
middle of the page

TextException() should be TestException()

Zhou Jing  Jun 03, 2010  Jul 08, 2011
Printed, PDF,
Page 524
code example

0000000d jle 0000002A
.....................
00000015 jae 0000002E

In the first statement of the aforementioned code instead of 0000002A must be 0000002E.
In the second statement instead of 0000002E must be 0000002A.
Indeed, if the index value is out of array boundaries, IndexOutOfRangeException must be thrown rather than normal returning from the method.

Yuriy  May 14, 2011  Jul 08, 2011
PDF, , Other Digital Version
Page 524
code example

Probably, there is a typo in the following line of the code:
00000017 movzx edx,byte prt [esi+edi+8] - instead of "prt" should be "ptr".

Yuriy  May 14, 2011  Jul 08, 2011
Printed
Page 533
7 line of code comment of Dispose(Boolean) method

Comment of Dipose(Boolean) method says when ReleaseHandle returns TRUE then ReleaseHandleFailed MDA is fired. However, that MDA appears when ReleaseHandle returns FALSE not true. Please refer: http://msdn.microsoft.com/en-us/library/85eak4a0.aspx

Note from the Author or Editor:
The text is actually correct as is although, I admit I could have stated it more clearly.

It says: If ReleaseHandle returned true, return
Else: Fire the ReleaseHandleFailed Managed Debugging Assistant (MDA)

Anonymous  Mar 22, 2010 
Printed, PDF,
Page 534
the topmost code

should be:

public abstract Boolean IsInvalid {
get; // A derived class overrides this property...
)

Zhou Jing  Oct 12, 2010 
Printed, PDF,
Page 534
2nd paragraph

I was confused when I read the following text: "...and this class will override the protected constructor...". As far as I know, constructors can not be virtual (and abstract, of course) and, hence, they can not be overriden. Am I wrong?

Note from the Author or Editor:
You are correct in that constructors cannot be overridden. I will rephrase this in a future edition. What I mean is that the derived class will define a ctor that invokes the protected ctor and the derived class will override the other abstract members.

Yuriy  Jun 17, 2011 
Printed, PDF,
Page 560
1st paragraph, 5th line

Written in the book : "then Object-B has been collected"
I think it's more correct if it's written : "then Object-B has been unreachable". 'Cause, the calling to GCHandle's Alloc method passing in the Weak flag.

Note from the Author or Editor:
If Object-B does not have a Finalize, then it has been collected. If it does have a Finalize, then it is unreachable. I will make this clearer in the next edition.

adaapanya  Mar 21, 2011 
Printed, PDF,
Page 560
WeakReference<T>

It is not clear why Dispose() of WeakReference<T> explicitly assign null to its field.

Since it is value type, the m_weakReference is copied as enclosing WeakReference<T> instance is copied.
Eventually, there will be multiple reference to underlying WeakReference instance from copied instances.
So it seems to be nonsense to assign null to the field of one of them via Dispose().
(I think it is useful if WeakReference<T> directly uses 'weak' GCHandle and implements Dispose pattern correctly.)

Note from the Author or Editor:
There are useful scenarios for having a value type implement IDisposable as it allows you to use them with C#'s using statement. And in my example, here I have a WeakReference<T> instance as a field in the class and calling m_weakDelegate.Dispose() does set its m_weakReference field to null allowing the WeakReference object to be GC'd as soon as possible. So, in my specific usage, I think it does make sense and is useful.

However, I agree with you that there is danger here if the value type is not used correctly (within the confines of a single method or as a field of a reference type). I'll re-think this for the next edition of the book. Perhaps, I'll just add a comment to this effect.

Also, the code shown for weak event handlers is very buggy and wrong. I have re-implemented all of these on my blog: http://www.wintellect.com/CS/blogs/jeffreyr/archive/2011/03/17/weak-event-handlers.aspx

YFujiwara  Jun 14, 2011 
Printed, PDF
Page 562
WeakDelegate class

Class WeakDelegate<TDelegate> (on page 562) has a logical bug and it simply will not work as expected. Implementation is creating following object structure:

[btnTest.Click] -strong-> [Weak Delegate] -weak-> [Real Delegate] -strong-> [DoNotLiveJustForTheEvent]

Suppose that our event consumer (DoNotLiveJustForTheEvent object from example at page 561) is still necessary and somehow we are holding a reference to it in our application - it will survive garbage collection but the real delegate will not - it will be garbage collected because nothing is holding a reference to it and despite the fact that our consumer is still alive, it will not receive events anymore.

The example from book (page 561) is working only because it is a very special case that will not work in reality ? during the first garbage collection both the real delegate and the consumer (DoNotLiveJustForTheEvent object) are collected.

I've described that problem in details on my blog: http://blackfoot.pl/2011/02/en-clr-via-c-3rd-edition-weakdelegate-logical-bug/

Note from the Author or Editor:
Yes, this code is not correct. I have corrected code but it is to much to post here. Check my blog for it: http://www.wintellect.com/Resources/Blogs. Also, I'll fix this in any future edition of the book.

Tomasz W?jcik  Feb 26, 2011 
Printed, PDF,
Page 573
Last paragraph (not including the code sample)

You say that "... the GCNotification class raises an event whenever a generation 0 or generation 2 collection occurs."
Your code sample for GCNotification class uses a destructor to invoke event delegates. In destructor you check whether desired generation (variable m_generation:int) is less or equal to generation of current object and if it is - you invoke the delegates:

if (GC.GetGeneration(this) >= m_generation) {
Action<Int32> temp = Interlocked.CompareExchange(ref s_gcDone, null, null);
if (temp != null) temp(m_generation);
}

However, that GC.GetGeneration(this) will return 2 not only after 2nd generation collection occured, but also after the 1st generation collection occured (during which object is promoted to 2nd generation and put to freachable queue, because it's registered for finalization) - after that finalizer is called and GetGeneration() returns 2 which is not the same as 2nd generation collection occured.

Note from the Author or Editor:
Yes, you are correct about this. A simple fix would be to save the generation to a field within the Finalize method and compare this to m_generation instead of calling GC.GetGeneration. Of course,. the error only occurs once and so I don't think it is a big deal either way.

Anonymous  Oct 09, 2010 
Printed, PDF,
Page 597
Ch22-1-AppDomains sample

The comment at the first line of Marshalling method has the word "that" printed twice:

//Get a reference to the AppDomain that that calling thread is executing in

artnib  Dec 05, 2010  Jul 08, 2011
Printed, PDF,
Page 600
From bottom line of page 600 to top 3 lines of page 601

The lines from "is not marked as serializable." to "at Program.Main()" might be duplicated in the list.

Anonymous  Sep 11, 2010  Jul 08, 2011
Printed, PDF,
Page 602
before the note

missing a space; newMarshalByRefType should be new MarshalByRefType

Giovanni Lagorio  Aug 29, 2010  Jul 08, 2011
Printed
Page 606
side note

"When I ran this code, it took 134,174 milliseconds to access the instance field of a NonMBRO class that is derived from Object, and it took 1,533,886 milliseconds to..."

To get the milliseconds value, I must change the following code:

Console.WriteLine("{0:N0}", Stopwatch.GetTimestamp() - time); // 134,174
...
Console.WriteLine("{0:N0}", Stopwatch.GetTimestamp() - time); // 1,533,886

To:

Console.WriteLine("{0:N0}", (Stopwatch.GetTimestamp() - time)
/(Stopwatch.Frequency / 1000)); // 30 on my machine
...
Console.WriteLine("{0:N0}",(Stopwatch.GetTimestamp() - time)
/(Stopwatch.Frequency / 1000)); // 818 on my machine

Zhou Jing  May 24, 2010 
Printed, PDF,
Page 608
2nd paragraph, 3rd line

It's written : create a MarshalByValType object in this new AppDomain
Should be : create a MarshalByRefType object in this new AppDomain

adaapanya  Mar 26, 2011  Jul 08, 2011
Printed, PDF, , Other Digital Version
Page 640
the last paragraph

"In the case of a nested type, Name returns the concatenation of the name of the containing type...", but when I debug it, the Name only returns the nested type's name, while the MemberInfo.ToString() method shows the concatenation.

Note from the Author or Editor:
OK, I fix this in the next edition.

Leon Zhu  Sep 13, 2011 
Printed, PDF,
Page 654
in code

There are several places in the source code that are very confusing,
First, for the try..catch block, after the TargetInvocationException has been caught, the catch block will check the inner exception and rethrow the exception if it is type ArgumentOutOfRanceException, why rethrow it here since the program execution will be blocked and the following code : Console.WriteLine("Property set catch."); will never get executed.
Second, for method BindToMemberThenInvokeTheMember(Type t), there're several places uses "obj.GetType()", such as
FieldInfo fi = obj.GetType().GetFiled("m_someField", c_bf); why not use t instead, since t is the method parameter, obj.GetType() is the same as t.

Note from the Author or Editor:
OK, I can remove the catch block in a future edition.
I like using obj.GetType() instead of t because I think the more common case is to start with an object (not a type).

Leon Zhu  Sep 15, 2011 
Printed, PDF,
Page 656
1st comment of UseDynamicToBindAndInvokeTheMember method

This comment duplicates the comment of BindToMemberCreateDelegateToMemberThenInvokeTheMember. This should be like "Construct an instance (You can't use dynamic infrastructure to construct concrete instance)."

Anonymous  Sep 24, 2010  Jul 08, 2011
Printed, PDF, , Other Digital Version
Page 658
1st item of bullet list

Type's static GetTypeHandle method returns the runtime handle of the type of specified object, not of the specified type object. For example:

// Pass the type
var h = Type.GetTypeHandle(typeof(Int32));
Console.WriteLine( Type.GetFromHandle(t) ); // Displays 'System.RuntimeType'

// Pass the instance
h = Type.GetTypeHandle(123);
Console.WriteLine( Type.GetFromHandle(t) ); // Displays 'System.Int32'

To convert a Type object to a RuntimeTypeHandle, just query Type's instance read-only TypeHandle property like the case of field and method.

Note from the Author or Editor:
This refers to the first bullet on the page.

YFujiwara  Sep 24, 2010  Jul 08, 2011
Printed
Page 659
The code that calls the Show method

The code contains calls to a Show method that is not printed in the book. You can see the Show method's code by downloading the code for the book from http://Wintellect.com, selecting Resources and then choose Books.

Jeffrey Richter
 
Feb 25, 2010 
Printed
Page 666
4th paragraph,

"If the type's fields don't exactly match the names of the fields..., then a SerializationException exception is thrown...". Actually when I tried if the deserialization implies an string "Name" property of an specific class, while the assembly provided an Int32 "Name" property, an ArgumentException will be thrown. Furthermore, if, the deserialization can imply an class possess more properties than the one applied by the actual assembly, the new properties will be set to their default value when initializes.

Leon Zhu  Sep 18, 2011 
Printed, PDF,
Page 670
3rd paragraph

The book says "When this method is called, all the serializable fields will be set correctly and then may be accessed to perform any additional work ...", the sentence should be corrected as follows "... is called, all the serializable fields should have been set correctly and ..."

Leon Zhu  Sep 19, 2011 
Printed
Page 672
1st paragraph

I experimented both the following 2 scenario,
1. Serialize an instance of TypeA which TypeA has one Name field,
Deserialize using another TypeA while TypeA has 2 fields, Name and ID, The deserializing can go successfully, the Id column will be set its default value.
2. Serialize an instance Of TypeA, TypeA has 2 fields, Name and ID,
Deserialize using Another TypeA, TypeA has 1 fields, Name. The deserializeing can go successfully, Name value is set correctly.

for my assembly is not strong named.

Leon Zhu  Sep 19, 2011 
Printed
Page 682
Code at bottom of page

The static field should be called "s_theOneObject"

Jeffrey Richter
 
Feb 25, 2010 
Printed, PDF,
Page 693
2nd paragraph

In the Thread Environment Block (TEB) paragraph:

"Each try block that the thread enters inserts a node in the head of this chain; the node is removed from the chain when the thread exists in the try block."


Should this be "when the thread exits" or "while the thread exists in"?

Note from the Author or Editor:
Yes, "exits" is correct.

Anonymous  Jul 04, 2012 
Printed
Page 724
Code at top of page

Missing space between CancellationTokenSource and cts

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed, PDF,
Page 725
Last code snippet

missing a space; varcts should be var cts

Giovanni Lagorio  Aug 29, 2010  Jul 08, 2011
Printed
Page 727
Code at bottom of page

The comment at the bottom of the page should say "// if n is large, ..."

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed
Page 727
code at middle of page

Missing space between enum and TaskCreationOptions.

Zhou Jing  May 18, 2010  Jul 08, 2011
Printed, PDF,
Page 727
Last paragraph

Missing space between 'Task<TResult>' and 'object'.

Daniel Fortunov  Apr 29, 2011  Jul 08, 2011
Printed
Page 729
Code at bottom of page

Missing space between CancellationToken and ct

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed
Page 730
Code in the middle of the page

Missing space between CancellationTokenSource and cts.

Zhou Jing  May 19, 2010  Jul 08, 2011
Printed, PDF,
Page 730
Code at top of page

The comment at the top of the page should say "// if n is large, ..."

Daniel Fortunov  Apr 29, 2011  Jul 08, 2011
Printed
Page 732
combinations of three flags

NotOnCanceld should be NotOnCanceled

Zhou Jing  May 19, 2010  Jul 08, 2011
Printed, PDF,
Page 732
First listing

Missed space between enum and TaskContinuationOptions(second line).

artnib  Jan 06, 2011  Jul 08, 2011
Printed
Page 733
Code in the middle of the page

Missing space between var and cwt

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed, PDF,
Page 735
2nd Paragraph, line 3

RanToCompleted should be RanToCompletion.

Daniel Fortunov  Apr 29, 2011  Jul 08, 2011
Printed, PDF,
Page 735

The text:
"A Task object is in the WaitingForActivation state if that Task is creating by calling..."
Should be:
"A Task object is in the WaitingForActivation state if that Task is *created* by calling..."

Daniel Fortunov  Apr 29, 2011  Jul 08, 2011
Printed
Page 736
Code on the page

Spaces are missing between some code identifiers:
var cts = new CancellationTokenSource();
var tf = new TaskFactory<Int32>(cts.Token,
var childTasks = new[] {
StringBuilder sb = new StringBuilder(

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed, PDF,
Page 736
Middle of code listing

Minor inconsistency:

On page 735 you state that "the easiest way to determine if a Task completed successfully is to use code like this: if (task.Status == TaskStatus.RanToCompletion) ..." (this is as opposed to !task.IsFaulted && !task.IsCancelled, presumably?)

However in the code listing on page 736 you use t => !t.IsFaulted && !t.IsCancelled as a way to select tasks that ran to completion.

Daniel Fortunov  Apr 29, 2011 
Printed, PDF,
Page 737
"Note" section

On page 737, at the "Note" section, you have written : "Note When calling TaskFactory?s or TaskFactory<TResult>?s static ContinueWhenAll and ContinueWhenAny methods, ...".
But as far as I know, neither "Task Factory" class nor "Task Factory<TResult>" class contains any static members.

Note from the Author or Editor:
Correct, these methods are not static. I'll fix in next edition.

Yuri  Jun 10, 2012 
Printed
Page 738
Code in middle of page

Space missing between internal and sealed

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed, PDF,
Page 741
Code listing

Missing space between type and name of all three properties in the code listing.

Daniel Fortunov  Apr 29, 2011  Jul 08, 2011
Printed
Page 742
Code at top of page

Missing space between SearchOption and searchOption.
Also a missing space between FileStream and fs.

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed, PDF, , Other Digital Version
Page 742-3
Code listing at bottom of page

Missing space between 'Boolean' and 'IsStopped'.
Missing space between 'Boolean' and 'IsExceptional'.
Missing space between 'Boolean' and 'ShouldExitCurrentIteration'.

Daniel Fortunov  Apr 30, 2011  Jul 08, 2011
Printed
Page 743
Code just below middle of the page

The first line of code is missing some space. it should like this: public struct ParallelLoopResult {

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed
Page 744
Code

There are spaces missing in the code:
IEnumerable source
orderby type.FullName

Jeffrey Richter
 
Feb 25, 2010  Jul 08, 2011
Printed, PDF,
Page 744
Code in middle of page

Code missing spaces:
public static ParallelQuery<TSource> AsParallel<TSource>(this IEnumerable<TSource> source)
public static ParallelQuery AsParallel(this IEnumerable source)

Errors like this appear careless when it's the 3rd edition...

Brandon Young  Jan 15, 2011  Jul 08, 2011
Printed
Page 754
1st paragraph

[quote]
When I run this on my machine, I get a result of 15,856,074 milliseconds.[/quote].

A millisecond (from milli- and second; abbreviation: ms) is a thousandth (1/1000) of a second. [wiki]

When I change the following code:

Console.WriteLine("Access time: {0:N0}", Stopwatch.GetTimestamp() - s_startTime)

to:

Console.WriteLine("Access time: {0:N0} ", (Stopwatch.GetTimestamp() - s_startTime) / (Stopwatch.Frequency / 1000));

I got the correct milliseconds result.

Zhou Jing  May 22, 2010  Jul 08, 2011
756
Figure 27-1

On #6, it reads "...Hardward does I/O;...". It should read "...Hardware does I/O;...".

Note from the Author or Editor:
Yes, "Hardward" should be "Hardware"

FrankL  Feb 05, 2010 
Printed
Page 759
the footnote

... if the running threads have lower priorities.

Or that should be "highter priorities"? I'm confused.

Note from the Author or Editor:
I do mean "lower priorities". As I reread the text , I see how it can be interpreted 2 ways. What I mean to say is that it is OK to have the CPU at 100% utilization without affecting responsiveness or context switching if the threads that are running are of lower priority.

Zhou Jing  May 23, 2010 
Printed
Page 763
1st paragraph

"Once a client connects, the ClientConnect method..."

"ClientConnect" should be "ClientConnected"

Zhou Jing  May 24, 2010  Jul 08, 2011
Printed, PDF,
Page 770
Line 2 of the Note callout

The following text:
The HTTP (RFC 2616) states that...
should read:
The HTTP Standard (RFC 2616) states that...

Daniel Fortunov  May 01, 2011  Jul 08, 2011
Printed
Page 780

It would be good to mention in the "FileStream-Specific Issues" section that all of the static convenience methods on the File class (such as File.CreateText() and File.OpenRead()) create a FileStream for synchronous access -- you must create the FileStream instance yourself if you want performant asynchronous operations.

The documentation does not make this immediately obvious.

Note from the Author or Editor:
OK, I agree withoy and can add this in a future edition.

Daniel Fortunov  May 01, 2011 
Printed
Page 788
the whole "Comparing the APM and the EAP" section

Should I change all EPMs to EAP?

Note from the Author or Editor:
Yes. Unfortunately, there is no standard acronym for this technology and I couldn't quite make up my mind as to which one to coin and so I inadvertently used two acronyms to mean the same thing.

Zhou Jing  May 27, 2010  Jul 08, 2011
Printed
Page 788
2nd paragraph

"...the EAP must allocate EventArg-derived objects..."

EventArg should be EventArgs

Zhou Jing  May 27, 2010  Jul 08, 2011
Printed
Page 789
2nd bullet item

PreFairness should be PreferFairness

Zhou Jing  May 27, 2010  Jul 08, 2011
Printed, PDF,
Page 790

In accordance with the Page 788 comment (and response) regarding EPM vs EAP; if EAP is the chosen term than "Event-based PM" in the table on page 790 should probably read "Event-based EAP" for clarity and consistency.

Note from the Author or Editor:
Agreed.

Daniel Fortunov  May 01, 2011  Jul 08, 2011
Printed, PDF,
Page 790

This table refers to RegisterWaitForSingleObject however this method is not discussed at all in the book until the following chapter. A footnote may be in order to point this out.

Note from the Author or Editor:
Yes, I agree. I'll fix in the next edition.

Daniel Fortunov  May 01, 2011 
Printed
Page 805
the final line

AllBegin should be AllBegun

Zhou Jing  May 29, 2010  Jul 08, 2011
Printed
Page 805
the footnote

AboutToBeging should be AboutToBegin

Zhou Jing  May 29, 2010  Jul 08, 2011
Printed
Page 806
code of AsyncCoordinator class, 2nd line, the comment

"Decremented by AllBegun"

AllBegun should be JustEnded?

Note from the Author or Editor:
Actually, I prefer "// Decremented by AllBegun when it internally calls JustEnded"

Zhou Jing  May 29, 2010  Jul 08, 2011
Printed, PDF,
Page 811
"The Interlocked Anything Pattern", line 3

The following text:
"It would be nice if the Interlocked class offered Multiple, Divide, ..."
should read:
"It would be nice if the Interlocked class offered Multiply, Divide, ..."

Daniel Fortunov  May 02, 2011  Jul 08, 2011
Printed, PDF,
Page 812
2nd paragraph, 3rd line

"derivedVal" should be "desiredVal."

Anonymous  Sep 21, 2010  Jul 08, 2011
Printed, PDF,
Page 822
First code listing

In the following code, taken from the Enter method:


// The calling now owns the lock, initialize the owning thread ID & recursion count
m_owningThreadId = currentThreadId;
m_recursionCount--;


The last line should read:

m_recursionCount++;

Otherwise, the thread that has first managed to get the lock would never release it, since m_recursionCount is tested for zero in the Leave method. Also, if the same thread gets the lock three times or more, the thread will actually release the lock but it'll also try to release it a second time, causing the Leave method to thrown an InvalidOperationException since it doesn't own the lock anymore.

Note from the Author or Editor:
Yes, you're right that this code is incorrect. At the end of Enter, I would change the line to "m_recursionCount = 1;" to fix the bug.

Jesus Requejo  Feb 17, 2011  Jul 08, 2011
Printed, PDF,
Page 829
"A Potpourri of Hybrid Constructs", line 4

The following text:
"...then your application avoids the performance of creating the object..."
should read:
"...then your application avoids the performance *hit* of creating the object..."

Daniel Fortunov  May 02, 2011  Jul 08, 2011
Printed, PDF,
Page 832
bottom of the page, in the code

the comment in LastTransaction.get says "has shared access", while it should say "exclusive"

Giovanni Lagorio  Aug 29, 2010  Jul 08, 2011
Printed
Page 838
note

ReaderWriterLockSlim was introduced in .NET Framework version 3.5 not 2.0. Please refer Version Information section of following: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

Anonymous  Mar 22, 2010  Jul 08, 2011
Printed, PDF,
Page 838
2nd Paragraph

Page 838 Paragraph 2 outlines why you don't think upgrading a ReaderWriterLockSlim is a useful thing, and ends with "This is the same as having the reader thread exit the lock and then immediately acquire it for writing."

This is not entirely accurate. If you exit the lock and re-acquire for writing there is a possibility of state being modified by another writer in the interim. This means that you will have to re-verify any conclusions drawn from inspecting state within the initial read-lock section after your re-acquire your write lock.

Also, you don't mention that the read lock must be explicitly acquired in "upgradeable mode" with EnterUpgradeableReadLock(), and only one thread can hold a read lock in upgradeable mode at any time (which ensures that you can upgrade without first releasing the read lock, and also without risk of deadlock).

Upgradeable mode becomes a problem if all your accesses acquire an upgradeable read lock, in which case you've effectively degraded to the equivalent of a single exclusive lock. If, however, you have multiple ways of accessing the protected data, and most of these require read-only access, then what's the problem with using an upgradeable lock in a location where you might need write access?

Note from the Author or Editor:
I could mention these methods in the next editon. I still belive they have very little value however in a real-life program.

Daniel Fortunov  May 02, 2011 
Printed
Page 839
middle of the page

"If RW==0 && WW = 0:"
should be:
"If RW==0 && WW == 0:"

Zhou Jing  Jun 02, 2010  Jul 08, 2011
Printed
Page 840
3rd bullet item

"Wake all reader blocked read threads"
should be
"Wake all blocked reader threads"

Zhou Jing  Jun 02, 2010  Jul 08, 2011
PDF
Page 850
inside Dequeue method

The following statement

Monitor.Wait(m_queue);

in method "Dequeue" should be

Monitor.Wait(m_lock);

snow bear  Jul 16, 2010  Jul 08, 2011
Printed
Page 858
code comments

// true if AddingComplete is called
should be
// true if CompleteAdding is called

// true if IsAddingComplete and Count==0
should be
// true if IsAddingCompleted is true and Count==0

Zhou Jing  Jun 11, 2010  Jul 08, 2011