I wrote a small wrapper of the Async library for Json.Net v5.06 from NuGet and after updating a number of Telerik packages my UnitTests started to fail with MissingMethodException .
I created a dummy non-Async method that works, so I got confused where the error is.
Project Target Platform
.Net 4.5
x86 CPU
Operation async
public class JsonSerialiser : ISerialiser { [InjectionConstructor] public JsonSerialiser(IStringCompression streamCompressor, ILog logger) { if (streamCompressor == null) throw new ArgumentNullException("streamCompressor"); if (logger == null) throw new ArgumentNullException("logger"); XmlConfigurator.Configure(); this.streamCompressor = streamCompressor; this.logger = logger; } public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { return await JsonConvert.SerializeObjectAsync(serialseObject); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } } }
Asynchronous Example
Now this code has been reset to check basic serialization, where I go to null checks in the class constructor.
private async void button1_Click(object sender, EventArgs e) { List<Part> parts = new List<Part> { new Part() { AbstractType = typeof(IOpcController), ConcreteType = typeof(OpcController) }, new Part() { AbstractType = typeof(ISerialiser), ConcreteType = typeof(JsonSerialiser) }, new Part() { AbstractType = typeof(IStringCompression), ConcreteType = typeof(StringGZipCompression)}}; string serialisedResult = string.Empty; JsonSerialiser serialiser = new JsonSerialiser(null, null); serialisedResult = await serialiser.SerialiseAsync<List<Part>>(parts); }
Async Result
This is a generation of MissingMethodException

Method not found: 'System.Threading.Tasks.Task`1<System.String> Newtonsoft.Json.JsonConvert.SerializeObjectAsync(System.Object)'. at Helper.Core.Serialisation.Json.JsonSerialiser.<SerialiseAsync>d__0`1.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine) at Helper.Core.Serialisation.Json.JsonSerialiser.SerialiseAsync[T](T serialseObject) at OpcTester.Form1.<button1_Click>d__9.MoveNext() in c:\Users\phil.murray\Desktop\tmp\OpcTester\Form1.cs:line 44
No Async Operation
Just to check if there was an asynchronous part of the method causing the problem, I wrote a non-asynchronous implementation.
public string Serialise<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { return JsonConvert.SerializeObject(serialseObject); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } }
No Asynchronous Implementation
private async void button1_Click(object sender, EventArgs e) { List<Part> parts = new List<Part> { new Part() { AbstractType = typeof(IOpcController), ConcreteType = typeof(OpcController) }, new Part() { AbstractType = typeof(ISerialiser), ConcreteType = typeof(JsonSerialiser) }, new Part() { AbstractType = typeof(IStringCompression), ConcreteType = typeof(StringGZipCompression)}}; string serialisedResult = string.Empty; JsonSerialiser serialiser = new JsonSerialiser(null, null); serialisedResult = serialiser.Serialise<List<Part>>(parts); }
No Asynchronous Result
The method completes and serializes the list into a string.
Invalid test case.
Test Name: SerialiserSerialiseObjectExists Test FullName: Helper.Tests.SerialiserTests.SerialiserSerialiseObjectExists Test Source: c:\Perforce\Development\SharedAPIs\Helper.Core\Helper.Tests\SerialiserTests.cs : line 38 Test Outcome: Failed Test Duration: 0:00:00.0116216 Result Message: Test method Helper.Tests.SerialiserTests.SerialiserSerialiseObjectExists threw exception: System.MissingMethodException: Method not found: 'System.Threading.Tasks.Task`1<System.String> Newtonsoft.Json.JsonConvert.SerializeObjectAsync(System.Object)'. Result StackTrace: at Helper.Core.Serialisation.Json.JsonSerialiser.<SerialiseAsync>d__0`1.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) a t System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine) at Helper.Core.Serialisation.Json.JsonSerialiser.SerialiseAsync[T](T serialseObject) at Helper.Tests.SerialiserTests.<SerialiserSerialiseObjectExists>d__3.MoveNext() in c:\Perforce\Development\SharedAPIs\Helper.Core\Helper.Tests\SerialiserTests.cs:line 40 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Asynchronous test without Json.Net
Just for arguments, I replaced the Json.Net call with a dummy task, and it worked, so the problem is calling Json.net using Await \ Async. Strange as it worked, and the version was not updated.
public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { //return await JsonConvert.SerializeObjectAsync(serialseObject); return await Task.Run(() => string.Empty); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } }
Question
Now, the asynchronous UnitTests method worked previously before I updated the Telerik management pack and I tested the operation in multiple instances of the real world. I'm not saying that updating Telerik caused a problem, as it could be a coincidence. A number of other asynchronous tests pass when testing other classes (not related to Json.Net).
Any idea what is wrong with the Async method and how to solve the problem?
Possible resolution
As I continued to investigate the problem, it occurred to me that the problem could arise in the Async call in the Json.Net library, so I wrapped up no Async call in the Task, as shown below, which worked
public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { //return await JsonConvert.SerializeObjectAsync(serialseObject); return await Task.Run<string>(() => JsonConvert.SerializeObject(serialseObject)); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } }
Out of interest, I downloaded the source for Json.Net and checked the JsonConvert.SerializeObjectAsync call, and it did the same, so again I'm not sure about the main problem.
public static Task<string> SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); }