Thursday, October 27, 2005 |
|
|
Concurrent Programming in Java, by Doug Lea, was recommended to me by two presenters at the Microsoft PDC 2005 as the best book about concurrent programming for .NET. It is an impressive book, and it seems fairly straightforward to translate the concepts from the Java world to the .NET Framework.
I can’t give this book a completely fair review, because I wasn’t able to finish it. The book is divided into four chapters; my current interest in concurrent programming was only able to get me through the first two. I don’t doubt that I will find additional value in this book the next time I am faced with a difficult concurrency challenge.
I really enjoyed the first two chapters, though, as they provide the language for discussing concurrent programming. For example, section 1.3 describes the “design forces” to consider when designing concurrent software:
- Safety demands that an object is always in a consistent state. Concurrency makes it possible for one thread to interfere with the operation of another thread acting on the same object, possibly resulting in an inconsistent state.
- Liveness demands that operations run to completion. Concurrent programming can permanently halt progress when two threads are waiting for locks held by the other thread, for example.
- Performance wants operations to run in a timely manner. Concurrency support adds overhead that can hurt performance.
- Reusability wants objects and algorithms to be reusable by different parts of the system. Concurrent programming adds a new dimension to the requirements of reusable software; specifically, clients must know to what extent a component is thread-safe.
Chapter 2 is all about keeping objects in a consistent state by ensuring that two threads cannot manipulate the same data at the same time, either by making objects immutable, or preventing objects from being accessed by other threads, or by synchronizing the use of objects with locks. Understanding of these concepts is crucial to writing safely concurrent code.
Section 2.2.7 is particularly interesting if you’re not familiar with the concept of a “memory model.” Basically, modern compilers and processors can rearrange the order in which statements and instructions are executed, as long as the end result is the same. This can cause very surprising behavior when one thread is observing the activity of another thread. The only practical way to ensure that each thread sees what you would expect it to see is to use synchronization; access to shared memory should always be protected by a lock.
I know that the book has more important concepts; perhaps I’ll make another attempt at reading chapter 3 some day. If you’re doing any concurrent programming at all, I highly recommend that you see how far you can get. |
10/27/2005 2:01:17 PM (Pacific Daylight Time, UTC-07:00) | | Books
|
|
|
|
Monday, October 24, 2005 |
|
|
This PDC 2005 session was about WinFS, the object-oriented storage system that Microsoft has been working on for years. It is certainly interesting, but still basically the same technology that they were talking about two years ago. It’s also hard to get excited about a technology that they’re not planning to ship until after Windows Vista ships in late 2006… |
10/24/2005 8:03:30 AM (Pacific Daylight Time, UTC-07:00) | | Development
|
|
|
|
Friday, October 21, 2005 |
|
|
I love writing extensible applications, so I was very interested in attending this PDC session. The obvious approach to writing managed add-ins is to simply load any assemblies that are registered as add-ins, use reflection to look for specially-marked types in each assembly, create instances of those types, and communicate with those instances. This session talked about potential problems with that approach and discussed solutions.
One problem is that old add-ins won’t work with new versions of the application (and vice-versa) because of strong naming. This problem is solved by using non-versioned, stable interfaces for any communication between the application and the add-in.
If the add-in assembly is loaded directly, the assembly can’t be unloaded if the add-in is unloaded. This can be solved by loading the assembly into its own app domain, or even in its own process. Also, the add-in must run under the same security as the application unless it is loaded into its own app domain or process. Another potential problem is that the add-in must use the same version of the CLR and the .NET Framework, but the only way around that is to load the add-in into a separate process.
Of course, loading an add-in into its own app domain has its own problems. Objects that are passed between the application and the add-in must be serializable or marshal-by-ref, which can be more work, and decreases performance. Loading an add-in into its own process provides even worse performance, and communication between the two becomes even more difficult.
The speakers thus recommended loading add-in assemblies into their own app domains, and spent the rest of the session explaining the add-in model used by the new System.AddIn namespace. Unfortunately, I was pretty lost for most of the presentation; it can’t be as complicated as it seemed…
In any case, I’ll still consider the direct approach for loading add-ins if I ever need them for a desktop application. Leaving an add-in assembly loaded even after the add-in is unloaded is not a significant problem for short-lived client apps. Giving add-ins full trust seems a bit dangerous, but if you trust an add-in developer enough to run their installer, it’s not a stretch that you need to trust their add-in as well. |
10/21/2005 8:31:56 AM (Pacific Daylight Time, UTC-07:00) | | Development
|
|
|
|
Wednesday, October 19, 2005 |
|
|
I read Effective Java, by Joshua Bloch, not because I ever write Java code (I don’t), but because it surprisingly was recommended as a valuable book for C# programmers. Sure enough, this book has excellent advice for programmers of any Java-like object-oriented framework. My favorites:
- Item 1: Consider providing static factory methods instead of constructors
- Item 6: Avoid finalizers
- Item 12: Minimize the accessibility of classes and members
- Item 13: Favor immutability
- Item 14: Favor composition over inheritance
- Item 15: Design and document for inheritance or else prohibit it
- Item 27: Return zero-length arrays, not nulls
- Item 29: Minimize the scope of local variables
- Item 30: Know and use the libraries
- Item 39: Use exceptions only for exceptional conditions
- Item 46: Strive for failure atomicity
One item that caught my attention was item 16 (“Prefer interfaces to abstract classes”), because it directly conflicts with Cwalina and Abrams’ Framework Design Guidelines (“Do use abstract classes instead of interfaces to decouple the contract from implementations”). Of course, both books are expressing a general preference, not a strict rule, and both books identify the situations where each construct is appropriate.
Some of the items are particular to Java, but they were still interesting as education on some of the differences between Java and C#. I just skimmed the last chapter (“Serialization”), which basically discourages the use of Java’s serialization mechanism anyway. Furthermore, I don’t know how it compares to .NET serialization.
All in all, it was definitely worth reading, and I highly recommend it to seasoned C# programmers. |
10/19/2005 4:10:02 PM (Pacific Daylight Time, UTC-07:00) | | Books
|
|
|
|
Tuesday, October 18, 2005 |
|
|
(Ah, “performant.” I used that word the other day while talking to my boss, and he wondered if I had made it up. It’s not actually a word, and most people talking about it on the Internet don’t seem to like it very much, but it works for me. I knew immediately what it was getting at – “having high performance,” basically. I wonder how long it will take to make it into the dictionary…)
Rico Mariani’s session was mostly about performance improvements to the .NET Framework 2.0. He talked about improvements to “ngen,” which should be good news for the startup time of client applications. He talked about “generic” collections – and warned against creating too many collection types that store less than 500 value type items. He talked about how “foreach” should now always be the optimal way to enumerate a collection. Garbage collection is faster, and it’s okay to call GC.Collect after the user does something that causes “mass extinction” of objects. Throwing exceptions is faster – though still discouraged for normal flow control. Security is faster, particularly for “full trust” applications. Reflection is faster – good news for users of custom attributes. Profiling is better. Delegates are faster. String hashing is faster. Et cetera. Basically, to “write performant managed code,” use the latest .NET Framework. |
10/18/2005 8:28:35 AM (Pacific Daylight Time, UTC-07:00) | | Development
|
|
|
|
Monday, October 17, 2005 |
|
|
Programming Windows Presentation Foundation is an outstanding introduction to the latest technology from Microsoft for building user interface for Windows XP and beyond. It is written by two knowledgeable and trustworthy authors, Chris Sells and Ian Griffiths, in a style that’s easy to follow. I’m going to need some actual experience under my belt before I really “get it,” but this book taught me far more than the online information that I’d read thus far.
It’s difficult to introduce so many new concepts in a linear fashion, so there were a few hiccups. I would like to have learned more about “dependency properties” before chapter 9, as they are really fundamental to the entire programming model of WPF. You might consider reading chapter 9 (“Custom Controls”) immediately after reading chapter 3 (“Controls”). I also would have liked to see more code and less XAML, though that may have made the book much longer for little benefit. At the very least, take their advice and skip ahead to Appendix A to help understand what sort of code the XAML is used to generate.
This book was written for WinFX Beta 1, so be sure to read the errata, as there have been important changes in the most recent releases. If that’s too bleeding-edge for you, feel free to wait until they publish the second edition of the book, after WPF actually ships. On the other hand, the fundamentals of WPF won’t be changing, so this book still provides an excellent introduction to the next wave of user interface programming for Windows. I, for one, am ready to get started! Goodbye GDI, hello WPF! |
10/17/2005 8:28:47 AM (Pacific Daylight Time, UTC-07:00) | | Books
|
|
|
|
Tuesday, October 11, 2005 |
|
Monday, October 10, 2005 |
|
|
C# Precisely, by Peter Sestoft and Henrik I. Hansen, is a concise overview of the C# language. It is clearly intended for programmers that are already somewhat familiar with the language, but want to fill in the details.
I picked it up not because I needed the overview – there was little that I didn’t already know – but because I had read great reviews on the presentation format of the book. The presentation is, in fact, pretty impressive. As you read the book, the left page contains all of the prose, which is information-dense yet quite readable, and the right page contains examples and their descriptions, numbered from the beginning of the book to the end for easy cross-referencing. In only 180 pages or so, this book manages to convey a lot of information very efficiently.
I would definitely recommend this book to anyone that wants to get familiar with the details of C#. Be sure to read the online errata, as some of the information on C# 2.0 is slightly outdated. Also, as mentioned in the preface, this book does not cover a few topics, the most important of which are destructors and finalization; be sure to find another source of information for the missing topics. |
10/10/2005 10:45:37 AM (Pacific Daylight Time, UTC-07:00) | | Books
|
|
|
|
Thursday, October 06, 2005 |
|
|
Brent Rector’s session was not what I had hoped it would be. I thought I was going to learn about the APIs, but the session was about some of the SDK tools. The session seemed pretty random; here are some of the interesting bits:
- The XSD tool will help you build an XML schema from a .NET class or an existing XML document, and it will build a .NET class from an XML schema.
- The SGEN tool will build XML serializer code so that it doesn’t have to happen via reflection at runtime.
- The Fusion Log Viewer can be used to see where your .NET assemblies are coming from, but the tool is ugly and finicky.
- The new Windows shell (code-named Monad) looks very cool, but I wonder if I’ll ever take the time to learn it. If you spend a lot of time writing batch files and one-off scripts, you should really appreciate its power.
- Perforator is a tool that can help diagnose WPF (Avalon) performance (frame rates, etc.).
|
10/6/2005 1:52:26 PM (Pacific Daylight Time, UTC-07:00) | | Development
|
|
|
|
Tuesday, October 04, 2005 |
|
|
I attended two Birds of a Feather sessions, which are informal sessions where the (generally small) audience is expected to participate in the discussion.
I started at Keith Brown’s “Writing Secure Code” session, but it ended up focusing on server security, which really isn’t relevant to what I do. So I switched to John Moody’s “Help! I Have to Manage Programmers!”, which was packed to the gills. Clearly this topic resonated with people, and there were lots of strong opinions in the audience. Much of the discussion was about task estimation. One interesting idea was to allow experienced programmers to estimate longer tasks, but require newer programmers to estimate shorter tasks.
For the next session, I returned to Keith Brown for “Writing Partially Trusted Code,” which was much more interesting to me than his first session, as it stayed more focused on client applications. I actually learned some things about .NET code access security, the most important of which was about assembly-level security attributes. Even though FxCop wants me to declare security attributes on my assemblies, the experts at the session insisted that it is often best to simply ignore that rule. That’s great, because I still don’t understand how I would use them. |
10/4/2005 10:33:02 AM (Pacific Daylight Time, UTC-07:00) | | Development
|
|
|
|
Monday, October 03, 2005 |
|
|
Effective C++, Third Edition, by Scott Meyers, contains a number of fundamental C++ guidelines that should be read by all C++ programmers. Having already read a previous edition of Effective C++, my expectation was that I would get a nice reminder of things I already knew. My hope was that I’d learn a few things that I didn’t already know, or had forgotten; here are some of those things:
- You can use the member initialization list of a constructor definition even when you want to default construct a data member (p. 29).
- A classic implementation of the copy assignment operator takes its argument by value (to make a copy of it) and then calls
swap on that argument (p. 56).
- Since compilers can reorder operations within a statement, very surprising things can happen in the face of exceptions (p. 76).
- Prefer non-member non-friend functions to member functions (p. 98). I remember this controversial item from the last edition, but it was good to read his rationale again.
- There are very peculiar rules about the
swap function. You need to consult item 25 (p. 106) before you attempt to write a non-throwing swap function for your classes. Even calling the swap function is complicated – you must not call std::swap directly, but should instead call it like this: using std::swap; ... swap(obj1, obj2);
- It never occurred to me to use an “interface class” for a single concrete class, merely to reduce compilation dependencies (p. 145).
- Use
using declarations to avoid hiding inherited names; you rarely want to hide inherited member functions when you add a new overload, but that’s what happens in C++ (p. 159).
- Include a definition for a pure virtual function if you want to provide a default implementation that must be explicitly requested (p. 167).
- I didn’t realize that “accessing names in templated base classes” was a problem; you’d think I’d have run into that before (item 43, p. 207).
- I also never realized that I’d need to “define non-member functions inside templates when type conversions are desired.” The only way to do that is with a friend function, even if the function doesn’t need special access to your members (item 46, p. 222).
|
10/3/2005 9:23:51 AM (Pacific Daylight Time, UTC-07:00) | | Books
|
|
|
|
|
|
|
| Archive |
| March, 2008 (1) |
| January, 2008 (1) |
| September, 2007 (1) |
| July, 2007 (1) |
| June, 2007 (3) |
| May, 2007 (2) |
| January, 2007 (2) |
| December, 2006 (1) |
| November, 2006 (2) |
| August, 2006 (6) |
| July, 2006 (3) |
| May, 2006 (4) |
| April, 2006 (2) |
| March, 2006 (1) |
| February, 2006 (1) |
| January, 2006 (1) |
| December, 2005 (2) |
| November, 2005 (5) |
| October, 2005 (11) |
| September, 2005 (7) |
| August, 2005 (1) |
| July, 2005 (2) |
| June, 2005 (2) |
| April, 2005 (5) |
| March, 2005 (11) |
| February, 2005 (6) |
| January, 2005 (2) |
| December, 2004 (1) |
| November, 2004 (1) |
| October, 2004 (3) |
| September, 2004 (1) |
| August, 2004 (5) |
| July, 2004 (10) |
| June, 2004 (3) |
| May, 2004 (5) |
| April, 2004 (3) |
| March, 2004 (10) |
| February, 2004 (10) |
| January, 2004 (15) |
| December, 2003 (1) |
| November, 2003 (2) |
| October, 2003 (13) |
| September, 2003 (20) |
| August, 2003 (24) |
|
|
|
|