(Packt) - this is the cheapest way to buy the book as far as I can see (49MB download! Mostly because it contains bin/obj directories for all solutions...) links if you don't want to buy it directly This book doesn't really compete with C# in Depth, but obviously the very fact that it's another book about C# at all means I'm probably not entirely unbiased. Arguably it also "competes" with my own (
read more »
I agree with Erik..... Jon's review is horrible. I've read nice comments about this book. Jon isn't serious.
You are right. In fact this book is great for beginners. You can have a look at the book here: http://www.packtpub.com/beginners-guide-for-C-sharp-2008-and-2005-threaded-programming/book
Yeah! The book is nice. We're using Hillar's book to teach parallel programming in Cordoba, Argentina. Internet is very unfair. People like Jon can post a fake review saying that Hillar wrote a book full of "bad practices". We admire Hillar in Argentina. He is the most important computer science writer in this country. I completely disagree with Jon.
PepeArgento, Cordoba, Argentina
Could you specify *exactly* which technical points you disagree with? Do you disagree that it's a bad idea to change a Windows Forms application to use MTA threading? (That's not supported.)
Do you disagree that it's better to fix memory issues by disposing of objects whose types implement IDisposable, rather than forcing garbage collection?
Do you disagree that the "optimization" used to populate the list of strings on page 120 is actually slowing things down by evaluating the Lines property twice? (Just calling the constructor with the collection will optimise the capacity.)
As ever, I appeal to people to dispute the concrete technical errors I've found with the book, rather than claiming that the book must be good and my review must be "fake" just because you like the author. Judge the book, not the author.
Jon
@Jon,
Have you ever written a parallelized database access as the book suggests? It works really fine!!!!!!! It seems you just care about micro-optimizations and not about the whole business. Hillar tries to teach multicore optimization and not studip micro-optimizations like the ones MVPs discuss about trying to catch some benefits from Bill & Steve.
Roy (again)
No, I'm not concerned with micro-optimisations. I'm mostly concerned with *correctness*. Things like making sure your WinForms apps use the [STAThread] attribute, as that's the only supported thread apartment mode for WinForms.
Correctness is far more important than micro-optimisation. It's usually easy to micro-optimise (after profiling) at a later date, but making an incorrect application correct is much harder. The fact that the micro-optimization which *is* given (P120, explained on P122) is actually slower than the more obvious call of "prlsSMSToEncrypt = new List(txtOriginalSMS.Lines);" is just an example of how it can backfire.
Now, to go back to my question: which of the technical points are you disagreeing with?
Jon
I'm very serious indeed.
I've read nice comments about this book too - and I believe they are written by people who don't realise that this book promotes bad practices *and* doesn't mention some of the very basic elements of threading in C#.
Please read the review carefully. If you own the book, try to find concrete things to disagree with. I'll happily make corrections to the review where I'm actually *wrong*. Unlike reviews which just say "it was good" I've given very specific details of what I don't like about it. If I'm wrong about those things, it should be easy to prove that, shouldn't it?
I'm deeply disturbed by the lack of accuracy in technical books these days. When that lack of accuracy is compounded by a failure to cover *essential* aspects of the topic in question, I see no reason to hide my disappointment.
Oh yes, I'm *very* serious about this review - and I absolutely stand by it. Please challenge the *substance* of the review: other people liking the book (without giving *nearly* the depth of detail that I have) doesn't invalidate the concrete points I've made at all.
There's no agenda here - I've written positive reviews for books which compete with my own very directly (see my reviews for C# 3.0 in a Nutshell and Accelerated C# 2008).
Jon
Jon..... You're talking about one of the best computer science Spanish authors. I've been in many of his conferences in Latin America. He can teach you assembler if he wants to. He works with electronics, embedded systems, and he was talking about multicore before Intel began talking about multicore. We're using Gaston's book examples to optimize medical imaging (my English is horrible, sorry). You should improve your review. You're talking about one of the most important computer science guys in Latin America. I am from Madrid, Spain. He writes articles in the most important programming magazine in Spain.
Watch the videos Gaston uploaded in youtube to show the examples working http://www.youtube.com/user/gastonhillar2009
Warm regards,
Diego Salinas Cortejo Madrid, Spain
None of that addresses any of the points made in my review. He could be an absolute genius for all I know, but that doesn't improve the book. It still teaches bad practices and ignores some of the most important parts of threading (particularly locking).
Jon
Jon, I believe you'r still in monoprocessor age... I bought the book after watching Hillar's videos in Youtube... The code works fine and your review is not telling the people the benefits of reading Hillar's book.
Egon
What makes you think I'm in a "monoprocessor age"? I've written extensively about threading - it's not like this is an unknown subject to me.
The code *can* work fine - if you don't run into subtle memory model issues. Hillar's code is not *safe* and more importantly the examples have been *chosen* to (mostly) get away without locking. In the real world you don't get to do this.
I believe that a beginner reading Hillar's book will come away with a lot of misinformation and bad practices.
Jon
Yeah! Jon, you have no idea of multicore. "I believe that a beginner reading Hillar's book will come away with a lot of misinformation and bad practices."
I believe you hate Hillar and you should **read** the book.
Roy
Jon is lying about this book. I own this book and it is really amazing. I'm sure he want to publish a competing title with Manning. Therefore, he is writing this nonsense.
Don't read his review. Instead, look for other serious reviews.
Erik
Yes, he is!
I misread your "competing title" bit before - no, I don't want to publish a competing title. If I were to write a book about threading, I'd want it to be competing with Joe Duffy's "Concurrent Programming on Windows" - but as Joe's book is *so* comprehensive and authoritative, there would be no point.
I have far more book projects than I can sensibly handle at the moment anyway, and none of them are on threading.
Jon
Please provide details of *specific* aspects of the review you disagree with. In particular, can you dispute that:
1) It never describes the lock statement, volatility, the memory model, synchronization using Monitor.Wait/Pulse
2) It recklessly changes the thread apartment model for WinForms apps, never explaining that this is a bad idea.
3) It encourages the use of GC.Collect on spurious grounds which would most likely be cured by disposing of bitmaps properly.
4) It "optimizes" list creation in a way which is hugely slow, uses Bitmap.Get/SetPixel instead of locking bits and efficiently reading/writing, and using string concatenation in a loop.
5) It reads data from threads after it's been written on a different thread with no attempt at locking.
These are just points *from memory*. This is *not* a good book. Oh, and it in no way competes with C# in Depth, which barely mentions threading.
If you're going to disagree with the review, please address specific points rather than just saying that it's obviously wrong simply because you like the book. I'd also appreciate it if you'd write the comments directly on my blog (http://msmvps.com/jon.skeet) - it makes it easier to keep track of that way.
Jon Skeet
Jon,
I've read your review and I'll prepare a post in your blog to let other readers know that you're trying to kill this book. yeah, the book has many horrible things, but it has many nice advices as well. Your reviews are horrible. I hate them, and you have the ability to post them everywhere. Are you an MVP? I'll post my comment in your horrible blog. I don't belong to this community, digwin, but I can't help commenting on this review.
Jeremy Sparks
Feel free to comment on my blog. I'm not trying to "kill" the book - I've given my honest opinion of it *with reasons*.
I feel no sense of shame in criticising a book for advising readers to force a GC (instead of disposing of bitmaps), or to change WinForms apps to use an MTA.
I do find it interesting how none of the comments so far which have criticised my review have disagreed with any specific points in it.
Contrary to Erik's post, there are no "lies" in my review. There are some matters of opinion (like coding style) but plenty of matters of hard fact which are easy to verify if you have the book.
Jon
@Jon:
I'm posting this in your blog,too
I disagree with some points of your review "Fairly disastrous advice (IMO) about both I/O and the GC" Did you test the examples in quad-core servers? They are pretty scalable...
"Using Control.Invoke/BeginInvoke to update the UI (although this comes very late in the book - chapter 10 out of 12)" I found the best example about this topic in Hillar's book
"Noting that sharing data between threads is difficult - but coming to the wrong conclusions (more later)" Hillar avoids locks, and talks about locks many times, I'm an average C# programmer. His code works. I don0't wanna write an OS kernel, as Hillar says in his comment
Exception "handling" (where "swallowing exceptions and just reporting them with Debug.Print" counts as "handling" apparently) I've learned exception handling in a C# programming book. I don't think it should be included as a great topic in a parallel programming book
Parallel Extensions from .NET 4.0, with both PLINQ and TPL Nice to find some information about future .Net in the book... Don't you think so? I haven't found comments about that in your review :(
"I find it absolutely incredible that a book on multi-threading in C# doesn't even mention the "lock" keyword." Are you joking???? Jon, Read the book again, be serious as another comment says.
"Okay, it's nice to be able to split tasks up completely independently where possible, but in the real world you sometimes have to use shared mutable state (or at least, it's often the simplest approach)." I believe the book is a nice introduction to parallel programming. Don't you think so? No, you don't, you think the book is horrible.... mmmm Maning, Maning Parallel Programming......
"When I first got the book, I looked up several entries in the index to see how they'd be handled. I was shocked to find that none of these have an index entry: BeginInvoke or Invoke" Contradictory....... Previously, you said: "Using Control.Invoke/BeginInvoke to update the UI (although this comes very late in the book - chapter 10 out of 12)".... mmmm Maning, Maning Parallel Programming......
"The concept of accessing state from multiple threads is glossed over for the entirety of the book. Basically whenever multiple threads want to make their results available, they put them in different elements of an array or list. There's an assumption that if you read from that array/list in a different thread, it's all okay. Likewise there's an assumption that it's appropriate to read integer variables written to in one thread from another thread without any locking, volatility or use of the Interlocked class. I'll come back to this topic when I tackle accuracy later on." The examples work fine and they scale in multicore CPUs. I've seen my Core i7 running with 8 threads, 5.8 times faster than the single threaded version...
"It's tricky with technical books: non-technical editors have good reason to be wary of going too far, as small changes in wording can have make a large difference semantically, but it does make a big difference to a book's readability when the language is clear and idiomatic." I understood everything explained in the book. Cool samples... NASA'S CIO hiring you...... Cool! :) You hate For Dummies. Don't you?
"It's not my preferred style to start with (particularly focusing on large GUIs instead of short, complete console apps) but I rarely felt particularly lost in the listings - there was usually enough context to hold onto. Here, I feel there's very little context at all. If you accidentally miss out a step, you'll have a really hard time working out which one it is or what's wrong." Do you love console applications? WE DON'T!!!!! WE HATE THEM! Average C# programmers hate console examples. I loved the samples in the book. Great examples that really work. What else does an average C# programmer want from a book like this one?
"We are told of FBI agents getting us capuccinos, the NASA CIO wanting you to use the Parallel Extensions CTP so that they can get free licences for Visual Studio 2010 and all kinds of other oddities." That's called sense of humor. You don't like humor in books. I do love humor in technical books. Cool! :)
"Apparently Hillar doesn't like the widely accepted practice of declaring variables at the point of their first use. Instead, most (but not all) of the time we're treated to all the variable declarations occurring at the top of the method, even if they're not used for a long time. This includes declarations of variables for use in loops. This took me right back to the 80s writing ANSI C again... " Does this really make sense in your review???? You're trying to find anything to destroy this poor man's book.
"Using directives aren't applied nearly thoroughly enough, leaving lots of explicit use of System.Diagnostics, System.Drawing, System.ComponentModel etc. Given the line length limitations in printed books, this is a real killer in terms of providing compact, readable code. Speaking of line length limitations, it would be really useful to actually acknowledge them - if a comment is going to span two printed lines, starting just the first one with "//" and leaving the second indented but not really a comment isn't a good idea." Out of interest..... Do the examples work? Do they use multicore CPUs???? Yeah!!!!! They exploit multicore... That's what average C# programmers like me are looking for!!!!!
"So, we've got code broken up into chunks which breaks the flow of the code, and I don't even like the style of the code. Still, I could live with that if it's good quality code..." The code exploits multicore CPUs......
"Data streaming is wasteful, because two threads might both want to do I/O at the same time - it's a better idea for each thread to load all the data it needs to and then start processing it." Did you test the example???? Did you test the example????? Guess what..... It runs faster!!!!!!!! Hillar is right. It runs faster!!!!!!
"The thread pool is used to queue threads with work to do. If there are already lots of threads busy, the new threads will wait until the old ones have finished." Most users have 2 GB RAM............. We're not anymore in the 90's...... Welcome to 2009, Jon. Who cares about the overheads, we want multicore CPUs to run faster applications!!!!!
Jon, I'm wasting my time. It seems you are a C# fan. I'm a performance fan. I love this book because it helped me to create high performance applications. You can keep posting coding issues, I'll keep reading Hillar's books.
"I'm sure there are good introductory threading books out there, but I'm afraid this isn't one of them." This is an excellent ***introductory*** threading book. Please, review your review.
Regards,
Roy Spencer (I love this book because it helped me to keep my job...........)
Roy, I've replied on my blog to the amount that managed to make it there, but some of it was truncated. So, here's my response to the other points:
Regarding console applications: Yes, I like console applications. They let me concentrate on learning about the topic instead of writing masses of useless GUI code. If someone is introducing a new topic to you, would you rather see 20 lines of code where 10 of them are relevant to the actual topic, or 100 lines of code where *still* only 10 of them are relevant? GUIs are bloated when it comes to code. They're (usually) a better *user* experience, but I don't think they're good for *learning* because there's so much which gets obscured by the extraneous code.
Regarding humour: yes, I like humour in technical books. I didn't find the "humour" here funny at all, just painful. Obviously humour is a subjective thing, but the tone of the book just wasn't right for me.
You've basically responded to all the "style" points by saying you don't care. Well, that's fine - but personally I like to see *readable* code in books. It makes it easier to learn that way.
Data streaming: Did you test the example by giving it several very large files at the same time? Then did you try it by streaming the data instead? What were the results like? What was the memory usage like? Why do you want to wait for the disk to have finished loading the last byte of the file before the *processor* starts using the first one? (Actually the best solution to this would probably be async IO, but that's a relatively advanced topic which genuinely doesn't belong in a beginner's book.)
Your thread pool response suggests you don't actually understand the comment I was making. The point is that the book is inaccurate by referring to *threads* being queued. *Tasks* are queued, which is the whole reason for the thread pool's existence.
I'm a performance fan too - but I'm also a *correctness* fan, both in my code and in books. When I see inaccuracies in books, why *wouldn't* I call them out?
I'm glad you've kept your job because of the book - but I hope you're not blindly following the practices espoused in it. I hope you're learning about locking, and how it's (in most cases) incredibly important when sharing data between threads. I hope you're *not* changing your Windows Forms apps to use MTA threading. I hope you're *not* using string concatenation in a loop. I hope you're *not* forcing garbage collection before every multi-threaded operation - and I hope you *are* disposing of bitmaps (and other disposable objects) when you're done with them.
Jon
Jon,
1. The book describes exploiting a multicore microprocessor. 2. Who cares? It works. 3. It is an example that tries to use as much memory as possible to explain GC. Perhaps, you can't understand it. Don't blame Hillar... :( 4. It optimizes for multicore. You're reading the book in a wrong way. Why did you review Hillar's book? What are you looking for in a parallel programming book? Parallel programming examples. 5. It avoids locks. In the examples Hillar presents in the book, that works for those examples. He talks about that. Did you read the book?
* This is a good book. * You are *not* a good book reviewer. * You are *not* a parallel programming guru. * Hillar *is* a parallel programming guru. I won't write in your blog. I don't like your blog and I don't want you to make money using Google ads... jeje
Goodbye. Have a nice day!
1) (About the lack of describing locks, volatility etc.) Yes, the book describes exploiting a multicore micro-processor - so long as you don't need to do anything which isn't embarrassingly parallelisable. In my experience, real life doesn't fit as neatly as that. In real life you *need* locking.
2) (About changing STAThread to MTAThread.) "Who cares? It works." Better hope you don't use the clipboard or anything else which uses COM under the hood. See http://blogs.msdn.com/jfoscoding/archive/2005/04/07/406341.aspx To quote: "Windows Forms is not supported within a MTA or free threaded apartment." Do you enjoy using a GUI framework in an unsupported way?
3) "It is an example that tries to use as much memory as possible to explain GC." The book states: "It is a recommended practice to force a garbage collection to happen before starting an intensive multithreaded algorithm." Every other commentator I've *ever* read (including CLR designers) recommends avoiding forcing garbage collection in all but the strangest of scenarios. Instead, you should work out why you're running into memory problems - and in this case it's because Hillar has been sloppy with bitmaps - something which is never explained, leaving beginners with the impression that it's fine to not bother disposing objects.
4) "It optimizes for multicore. You're reading the book in a wrong way. Why did you review Hillar's book? What are you looking for in a parallel programming book? Parallel programming examples." I'm looking for a book which talks about the *real* world - where you typically need to *safely* share data between threads. That requires volatility and/or locking.
5) "It avoids locks. In the examples Hillar presents in the book, that works for those examples. He talks about that. Did you read the book?" Actually, Hillar's code isn't guaranteed to work due to memory model issues. He uses lists without any synchronization. Look at the docs for List: "A List can support multiple readers concurrently, as long as the collection is not modified." Shame that the list is being modified in Hillar's examples. However, even if the examples *did* work, the book would be ignoring the huge range of problems (far more common in the real world, IME) that *do* require locking. A beginner's multithreading book which doesn't mention locking is like a beginner's C# book which doesn't mention strings.
Hillar may well be a multi-threading guru, but he doesn't demonstrate that in this book.
Jon
Jon,
You are still being aggressive in this comment. Stop being aggressive before asking me "to ask people to stop being aggressive with you".
This sounds a bit rude: "Hillar may well be a multi-threading guru, but he doesn't demonstrate that in this book.".
"However, even if the examples *did* work"...... I see, you didn't run the examples and you are talking about them..... Well, Jon. I'm impressed.
Warm regards,
Gastón Hillar
I think you missed the point of my "even if the examples *did* work" section. I'm saying that there are problems even with the examples which *are* there (mostly in terms of the memory model), *as well* as ignoring the set of problems which require locking.
Yes, the examples may "work" on first sight - even on most computers. But some of them are not *guaranteed* to work, because they ignore the memory model.
As I'm sure you know, just running a parallel program and looking at the results for a single test run (or a hundred, or a thousand) isn't enough to assure correctness.
If you want me to go and find a specific example of where you're reading a value from the UI thread after it's been set in a worker thread, but with no appropriate memory barriers, I can go through the book and find one. (It's not a problem with *all* the examples, certainly - just some.) This sort of subtle problem is exactly the kind of thing I've been talking about.
Jon
@Jon,
The examples *do* work in dual-core and quad-core computers. Why don't you talk about the chapter covering ConcurrentQueue... Hillar, sorry, I can't help attacking Jon's review. Jon, the UI thread is queued, isn't it? The examples work. You are trying to say that the book is horrible. Show us the exceptions raising while running the examples in a video..... jajaja, you can't do that.....
Roy
Roy, if you want the gory details about why the code is broken, I can go into them with you - although email would probably be better than here (skeet@pobox.com). I'm not talking about exceptions getting thrown - I'm talking about the UI reading a stale value because non-volatile variables are being used without locking. You can read about the .NET memory model on Joe Duffy's blog:
http://www.bluebytesoftware.com/blog/2007/11/10/CLR20MemoryModel.aspx
(Read the referenced article at the top first.)
The Int32 variables which are set in background threads and then read in the UI thread aren't thread-safe. The details on P123 of the book are inadequate. Even though Int32 is a thread-safe type in itself, that doesn't mean it's safe to access Int32 variables from multiple threads without careful measures such as use of the Interlocked class, the volatile modifier, or locking. Writes to Int32 variables are guaranteed to be atomic, but that doesn't mean that reads will always see the latest value. (Many people confuse atomicity and volatility, which is a shame.)
The result of this is that the UI in some of the examples isn't guaranteed to show the latest values. It usually will - you'd have to be very unlucky to see the problem. A side effect of the methods called may well be to act as memory barriers - but these are incidental side effects which aren't guaranteed. How much harm is there in seeing an incorrect value in a UI, probably just briefly? Not a lot. But now imagine that the incorrect value is the amount of money in your bank account. It's been updated by one thread and read by another. Don't you really, *really* want to see the updated value?
See section 12.6 of the ECMA 335 CLI spec (partition 1) for more about the CLI memory model, although the .NET 2.0 model is somewhat stronger (thankfully).
For an example showing exactly this sort of problem, drop me a mail. I've got a console app which *usually* demonstrates it (although it depends on how you build and your CPU architecture). If you're really averse to looking at console apps I can whip up a GUI app round it, although it'll be harder to see the relevant code amongst all the GUI crud.
If you're really interested in discussing multi-threading, I'm more than happy to go into this with you. If you actually just want to insult me, I'd rather not waste the time.
Jon
Hi there,
PLEASE, READ CAREFULLY AND STOP ATTACKING JON!!! PLEASE, READ CAREFULLY AND STOP ATTACKING JON!!! I am the book's author. I've seen the comments here and some in Jon's blog. I've recently registered in digwin to post this comment. His review is a bit aggresive and he is obviosly not going to change a line, because he read the parts that he wanted from the book and he took everything out of context. I agree. I don't like the way Jon writes in his blog, I don't like the way Jon defends his position, I don't like Jon's bad humor. I belive Jon doesn't have real life hard-core parallel programming experience with huge applications. Therefore, he insists in his Console.Writeline examples (most real-life programmers hate those examples). Jon loves those examples and he reads the lines he wants in a book to destroy it. That's what he does. That's his business in his blog. No matter my responses, he will still post anywhere that my book is horrible. It's his point of view. It's the point of view of an MVP. However, he is an MVP who thinks that everything should be explained using Console.Writeline. Can I go on discussing with Jon? Does it make sense? No, it doesn't. Why? Because he is always going to read what he wants to read. However, I've asked Jon by e-mail to keep a professional discussion about this. Please, please, please, stop the aggression. Stop the aggresive comments. Time will say whether Jon is right or not. The book has a sample chapter. Anyone can read it. The book has examples. Anyone can download the code. The book tries to reproduce some difficult to reproduce situations. Jon tries to be negative about everthing. He explains that string concatenation is a bad practice... It is used in samples that try to show an encryption algorithm that must steal some CPU time. Jon'll never catch that. He wants C# code perfection combined with Console.Writeline examples. Nobody will learn real life parallel programming situations with that examples. Jon doesn't understand the book. There's nothing I can do to change that. He'll do everything to kill the book everywhere. The real-life programmers will determine whether Jon is being sincere or not. I don't like violence. I don't like aggressions. I don't like rude comments. I like points of view and a serious professional discussion. By the way, I don't believe I'm going to be able to keep a serious professional discussion with Jon. However, I must try and, please, STOP AGGRESSIVE COMMENTS. Those who love the book should post that in other blogs. Jon's blog is going to keep talking negative things about the book. I've never seen a situation like this in my whole life. Jon's dedication to destroy the book is just amazing. However, I must respect his point of view and everybody should.
Thank you very much.
Yours sincerely,
Gastón C. Hillar
OK......... It's difficult.
Roy
Thanks Gaston. I quite agree that if you like the book, the best thing to do is praise it *in detail* elsewhere. Hint: Amazon reviews make a big difference to sales.
I would like to say that I am not trying to "destroy" the book though. If I wanted to do that, surely I would post my review as widely as possible - which I certainly haven't done. I *haven't* posted an Amazon review, and won't do so. I haven't submitted the review to Slashdot, Digg, Reddit, etc. I will, however, defend both the sincerity and technical accuracy of the review. It's frankly best if that's on my blog, as that's the definitive source for the review - but I'll keep watching this forum as well.
So far I seem to be the only one on digwin who dislikes the book, but should anyone else want to join in, I want to make the same basic point as Gaston: the discussion should be about the book, *not* about the person.
Jon
@Jon,
One question: Did you like the debugging chapter? Isn't it useful? Did the pixel changing application run faster in a quad-core? Did you run the examples? Did you read the Beginner's Guide guidelines? Packt has a new series, "Beginner's Guide". The book is about multicore. Do you really know about multicore? I guess you don't.
Roy
I liked some of the tips from the debugging chapter, yes. And yes, the pixel changing application scales - but it still runs slower than if it didn't call GetPixel and SetPixel on each individual pixel. You can scale *and* make things faster on a per-thread basis at the same time.
Just because something's a beginner's guide doesn't mean it can't encourage best practices. Quite the reverse, in fact. Now, rather than making presumptions about my knowledge of threading, do you have any concrete disagreements with the technical criticisms I raised in the review?
Jon