I’ve recently wanted to demonstrate the relevance of the .Net ReaderWriterLock[Slim] synchronization primitives.
It’s good to hear from the vendor that it’s better, faster, stronger, but when you can it’s always good to evaluate it yourself; not that I don’t trust vendors, but because I like to have hard numbers, particularly when I assert something that can be critical for my participants’ developments.
So I’ve built a small, simple and I hope relevant benchmark to measure the performance impact of ReaderWriterLock[Slim] compared to the naive and uniform use of a Monitor using the C# lock construct.
I wanted to check these two things:
that the RW locks behave as advertised,
what is the profile of the gain function.
In this article I’ll explain the rationales behind the benchmark, how I’ve implemented it and finally present the results.
First a warning, this is a difficult article which goes really deep inside the .Net machinery so if you don’t get it the first time (or even the second or third time…) don’t worry and come back later. 🙂
For a training session I’ve taught at the end of last year I wanted to demonstrate some subtleties of multi-threading, and more specifically some memory visibility issues that should cause a program to hang.
So I developed a small sample that I expected would be showing the issue, but instead of hanging as expected the program completed!
After manipulating the program further I obtained the behavior I wanted, the program was hanging, but it still didn’t explained why it managed to complete with my original version.
I suspected some JITter optimizations, and indeed it was the case, but I needed more information to completely explain this strange behavior.
As often, the StackOverflow platform was of great help; if you’re curious you can have a look at the original SO thread.
In this article I’ll “build” and explain the issue step by step, trying to make it more understandable than the SO thread which is indeed quite dry.
This is a small article about an issue I had recently trying to save some big documents represented as .Net objects in MongoDB using the MongoDB .Net driver.
While saving a “relatively” big document I’ve received the following exception:
System.IO.FileFormatException: Size 32325140 is larger than MaxDocumentSize 16777216.
at MongoDB.Bson.IO.BsonBinaryWriter.BackpatchSize() in c:\projects\mongo-csharp-driver\MongoDB.Bson\IO\BsonBinaryWriter.cs:line 697
at MongoDB.Bson.IO.BsonBinaryWriter.WriteEndArray() in c:\projects\mongo-csharp-driver\MongoDB.Bson\IO\BsonBinaryWriter.cs:line 294
at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`1.Serialize(BsonWriter bsonWriter, Type nominalType, Object value, IBsonSerializationOptions options) in c:\projects\mongo-csharp-driver\MongoDB.Bson\Serialization\Serializers\EnumerableSerializerBase.cs:line 408
at MongoDB.Bson.Serialization.BsonClassMapSerializer.SerializeMember(BsonWriter bsonWriter, Object obj, BsonMemberMap memberMap) in c:\projects\mongo-csharp-driver\MongoDB.Bson\Serialization\Serializers\BsonClassMapSerializer.cs:line 684
at MongoDB.Bson.Serialization.BsonClassMapSerializer.Serialize(BsonWriter bsonWriter, Type nominalType, Object value, IBsonSerializationOptions options) in c:\projects\mongo-csharp-driver\MongoDB.Bson\Serialization\Serializers\BsonClassMapSerializer.cs:line 432
at MongoDB.Driver.Internal.MongoInsertMessage.AddDocument(BsonBuffer buffer, Type nominalType, Object document) in c:\projects\mongo-csharp-driver\MongoDB.Driver\Communication\Messages\MongoInsertMessage.cs:line 53
at MongoDB.Driver.Operations.InsertOperation.Execute(MongoConnection connection) in c:\projects\mongo-csharp-driver\MongoDB.Driver\Operations\InsertOperation.cs:line 97
at MongoDB.Driver.MongoCollection.InsertBatch(Type nominalType, IEnumerable documents, MongoInsertOptions options) in c:\projects\mongo-csharp-driver\MongoDB.Driver\MongoCollection.cs:line 1149
at MongoDB.Driver.MongoCollection.Insert(Type nominalType, Object document, MongoInsertOptions options) in c:\projects\mongo-csharp-driver\MongoDB.Driver\MongoCollection.cs:line 1004
at MongoDB.Driver.MongoCollection.Save(Type nominalType, Object document, MongoInsertOptions options) in c:\projects\mongo-csharp-driver\MongoDB.Driver\MongoCollection.cs:line 1426
Well the message is clear: seems like I’ve exceeded the MongoDB max document size threshold which is 16MB, fair enough this is quite a sane design decision.
First I’ll explain why I had this issue, then how I’ve solved it.
As you may know event handlers are a common source of memory leaks caused by the persistence of objects that are not used anymore, and you may think should have been collected, but are not, and for good reason.
In this (hopefully) short article, I’ll present the issue with event handlers in the context of the .Net framework, then I’ll show you how you can implement the standard solution to this issue, the weak event pattern, in two ways, either using:
the “legacy” (well, before .Net 4.5, so not that old) approach which is quite cumbersome to implement
the new approach provided by the .Net 4.5 framework which is as simple as it can be
Recently I’ve worked with a web API, the Cometdocs API, in order to use their converter of documents, particularly for automating some conversions from PDF documents to Excel spreadsheets for data extraction.
I wanted to use this API from my two favorite development platforms: Java and .Net/C#, so I needed to build what is called a language binding, i.e. a small library that acts as a proxy between the application code and the web API.
The development of these two bindings was really interesting from a technical point of view, and I’ve learned a bunch of things during the process.
I’d like to share the interesting stuff with you, it should be of interest even if you don’t have any plan for interacting with a web API because all the technologies and techniques I’ve used (the HTTP protocol, JSON data binding, SSL/TLS…) are applicable to other types of developments.
It seemed technically feasible because Python has a remarkable tool to interact with native code: the ctypes module.
The only issue is that ctypes only supports C interfaces not C++ classes so in this case it can’t directly use the YahooAPIWrapper class.
In fact it’s a minor issue because this kind of situation is well known and a well documented pattern exists to circumvent it: building a C wrapper around the C++ API.
This looks a little crazy because you now have 2 layers between the Python client code and the C# Yahoo API:
Python -> C wrapper -> C++/CLI wrapper -> C# API
So, while I don’t think this layering could have any usefulness in real-life, this was a challenging and interesting question.
Looks simple no? Well, as you know when you start to pile up heterogeneous layersunexpected issues can appear and this is exactly what happened there, and it has revealed one that is worth talking about.
So keep reading!
Sometimes we need to modify some global state, but when we do that it’s critical to ensure we leave things as we’ve found them; you know like when you lift the toilet seat: forgetting to put it down afterwards could get you in trouble!
It’s similar in programming and you need to use the right tools and practices.
In this article I’ll show you how they can be used to scope global state changes in a fluent manner, a pattern I’ve used for years to enhance reusability and readability of this kind of code.
In the first part I’ll illustrate this pattern with a small and hopefully fun example, and then in the second part I’ll describe how it can be applied to other situations like culture settings and Excel development. Continue reading →
This article replaces the previous one with the same title.
Indeed the previous C++/CLI wrapper implementation had a flaw that created memory corruption. This issue has been fixed in the following implementation.
Moreover I’ve used it as an opportunity to greatly enhance the content, especially the description of the C++/CLI wrapper implementation, design rationales being now included.
The article has been updated on the 19th of June 2016 to integrate 3 fixes:
the YahooAPIWrapper‘s destructor is correctly declared in the header file to avoid memory leaks,
the YahooAPIWrapper‘s definition/cpp file does not redefine the class and the __declspec(dllexport) metadata has been moved to the header file to avoid compilation errors,
the YahooAPIWrapper‘s and native C++ program’s implementations have been updated to take into account the new fields names of Yahoo API to avoid runtime exceptions.
When it comes to software development in a professional environment, heterogeneity is the rule not the exception: you often need to interact with systems developed with other technologies.
I’ve been recently faced with such a situation: a team that uses only native C++ needed to retrieve data using the object-oriented API of another team that develops only in .Net with C#.
This is a relatively uncommon scenario (just look at the number of articles on the subject), the standard case being new systems based on the .Net platform, developed in C# or VB.Net, needing to interact with legacy systems developed in native C++.
I’ve used the C++/CLI platform due to its unique ability to mix managed (.Net) and native code in one place and is then the ideal tool for building bridges between these two worlds using simple wrappers: the native face of the wrapper can be consumed by the legacy components and its managed face can directly use the C# API.
In this article I’ll illustrate how I’ve tackled the issue by building a simple C++/CLI wrapper, using a similar use-case: market-data retrieval from Yahoo.