.NET 4.5 Improves to the Base Class Library
The Base Class Library forms the core of the .NET development platform. No matter what profile or front-end technology you choose, the BCL classes are invariably found throughout your application. Here’s what to expect from the BCL in .NET 4.5:
The Stream, TextReader, and TextWriter classes all got new async methods for the more expensive operations. By expensive we mean, “it is possible to do a lot of work in one operation”. Something like TextReader.Peek is not going to get an async version. The reasoning behind this is, to put it bluntly, async operations are not cheap. They require allocating a Task object, probably context switching, possibly cache invalidation, and in general are not suitable for use in tight loops. Immo Landwerth continues,
The general guidance is: Try to make your asynchronous operation as chunky as possible. For example, if you want to read 1,000 Int32s from a stream using BinaryReader, it’s better to run and await one Task to synchronously read all 1,000 than to individually run and await 1,000 Tasks that each reads only a single Int32.
Speaking of BinaryReader, you can now tell it to not automatically close the stream that it wraps. This feature is also available for BinaryWriter, StreamReader, and StreamWriter.
Immo also mentioned that .NET BCL is now using the open source library zlib to implement the System.IO.Compression namespace. This includes fixing the performance for DeflateStream as well as the new ZipArchive class. This isn’t the first time zlib was licensed by Microsoft, it is also used in Windows Zip file support and WPF.
We already talked about the read-only collections in .NET 4.5, nothing significant has changed since then. A notable missing feature is IReadOnlySet to match HashSet and ISet.
The abstract class Comparer<T> picked up some functional programming goodness. Instead of explicitly implementing this class you can call Comparer<T>.Create, pass it in a comparison function, and let it take care of the rest.
The little known ArraySegment<T> structure got a major face-lift and for the first time actually implements the interfaces that would make it useful such as IEnumerable and IList<T>. Still, it only works on naked arrays and most developers prefer to use higher level collection classes such as List<T>.
AssemblyMetadataAttribute is now the standard way of assigning arbitrary key-value pairs to an assembly. It is a little unclear why you would use this instead of just defining a custom attribute, but it is there if you want it.
Console now lets you know if the input, output, and error streams have been redirected. You would mostly use this to disable features that rely on setting the cursor position or changing the screen color. You can also change the encoding to Encoding.Unicode if you need to support additional characters.
WeakReference<T> offers a type-safe alternative to WeakReference. In order to eliminate a long standing race condition, WeakReference no longer offers the separate IsAlive and TryGetTarget methods. Instead they have been combined into TryGetTarget.
Unfortunately it doesn’t look like we are going to see a matching WeakDelegate, which, if it existed, would make implementing weak events much easier.
Regex now supports a Timeout property. This is an essential tool to avoid denial of service attacks when users are allowed to inject arbitrary regular expressions.
zlib in 4.5
Good to know that, the previous DeflateStream was a disaster, not only performance-wise, I hope this works better now.
Still, I miss some things:
1) to create "user friendly" enums for low level apis does not always help. CompressionLevel.Optimal, Fastest,NoCompression is not more clear than the (quite standard) integer values: compression level =0 .. 9. Worst off all, that's irritating, because it hides the true zlib level used (I can't compare) and prevents me to use any level in the range 0..9. With no good reason, I'd bet.
2) Apart from compression level, DEFLATE algorithm has an important parameter, the "strategy": why don't MS let me choose that? If they are really using zlib, that should be trivial to implement.
Re: zlib in 4.5
1. DeflateStream does not let you setting the dictionary (compare with docs.oracle.com/javase/1.5.0/docs/api/java/util... ).
2. Deflate compression is wrong for empty input. It returns an empty output, the correct is (0x3 0x0). And, yes, empty input is perfecly valid input and sometimes necessary (and easy to catch if you do unit tests)
3. I want to extend its behaviour so that, after DeflateStream has ended, I add 4 trailing bytes (CRC) to the output. It should be trivial. Guess what. It's not. Because apparently DeflateStream has some internal buffers that only get flushed when I call Close() (Flush has no effect, and there is no "End" method -as Java). Then, I must call Close() , but I cannot do that if leaveOpen=false, as Close() flushes the data and closes the underlying stream. Then, my class must save the flag leaveOpen, and call the constructor of DeflateStream with leaveOPen=true always, and do the close-underlying-stream-if-should itself. Quite contrived -and idiotic. But wait, there's more. When I call DeflateStream.Close() (with leaveOpen=true), and I try to access the baseStream to continue working with it... it's null (WTF? why?) So, I must save a copy of the reference before calling Close()... Aggghhhh
Roy Rapoport Aug 28, 2014