JsonConvert.Serialize Fails Silently

I ran into an interesting issue with JSON.NET over the weekend. Specifically, while I was serializing an object, it would fail silently. No exception was raised (or could even be trapped with a try-catch). However, the call to Serialize did not return and the application terminated.

The specific situation in which the call to Serialize was being made was the following:

List<Customer> _customers;

Task creationTask = new Task(() =>
{
    _customers = new List<Customer>();
   // Do stuff to build the list of customers
});
creationTask.ContinueWith(() =>
{
   serializeCustomer();
});

creationTask.Start();

Now the actual call to JsonConvert.Serialize is found in the serializeCustomer method. Nothing special there, other than the method that actually fails. But the reason for the failure is rooted in the code snippet shown above.

This was the code as originally written. It was part of a WPF application that collected the parameters. And it worked just fine. However the business requirements changed slightly and I had to change the WPF application to a console app where the parameters are taken from the command line. No problem. However while there was a good reason to run the task in the background with a WPF application (so that the application doesn’t appear to be hung), that is not a requirement for a console app.  And to minimize the code change as I moved from WPF to Console, I changed a single line of code:

creationTask.RunSynchronously();

Now the call to JsonConvert.Serialize in the serializeCustomer method would fail. Catastrophically. And silently. Not really much of anything available to help with the debugging.

Based on the change, it appears that the problem is related to threading. Although it might not be immediately obvious, the ContinueWith method results in the creation of a Task object. This process represented by this object will be executed in a separate thread from the UI thread. So any issues that relate to cross-threading execution has the potential to cause a problem. I’m not sure, but I suspect that was the issue in this case. When I changed the code to be as follows, the problem went away.

List<Customer> _customers;

Task creationTask = new Task(() =>
{
    _customers = new List<Customer>();
   // Do stuff to build the list of customers
});

creationTask.RunSynchronously();
serializeCustomer();

Now could I have eliminated the need for the Task object completely? Yes. And in retrospect, I probably should have. However if I had, I wouldn’t have had the material necessary to write this blog post. And the knowledge of how JsonConvert.Serialize operates when using Tasks was worthwhile to have, even if it was learned accidentally.