awaiting Func<XmlReader, Task<TValue>> throws "NullReferenceException"
chrfin opened this issue · comments
I have the following code (simplified):
Func<XmlReader, Task<TKey>> readKey = parameterValue;
var key = await readKey(reader).ConfigureAwait(false);
and if I remove the ConfigureAwait(false)
from these I get the following during build:
Error 1 Fody: An unhandled exception occurred:
Exception:
Object reference not set to an instance of an object.
StackTrace:
at Mono.Cecil.ImportGenericContext.TypeParameter(String type, Int32 position)
at Mono.Cecil.MetadataImporter.ImportTypeSpecification(TypeReference type, ImportGenericContext context)
at Mono.Cecil.MetadataImporter.ImportType(TypeReference type, ImportGenericContext context)
at Mono.Cecil.MetadataImporter.ImportTypeSpecification(TypeReference type, ImportGenericContext context)
at Mono.Cecil.MetadataImporter.ImportType(TypeReference type, ImportGenericContext context)
at Mono.Cecil.ModuleDefinition.Import(TypeReference type)
at ConfigureAwait.ModuleWeaver.AddAwaitConfigToAsyncMethod(TypeDefinition type, Boolean value) in C:\projects\configureawait\src\ConfigureAwait\ModuleWeaver.cs:line 95
at ConfigureAwait.ModuleWeaver.ProcessType(Nullable`1 assemblyConfigureAwaitValue, TypeDefinition type) in C:\projects\configureawait\src\ConfigureAwait\ModuleWeaver.cs:line 69
at ConfigureAwait.ModuleWeaver.Execute() in C:\projects\configureawait\src\ConfigureAwait\ModuleWeaver.cs:line 41
at lambda_method(Closure , Object )
at InnerWeaver.ExecuteWeavers() in c:\ConsoleBuildAgent\work\ed448661dbb30d2e\FodyIsolated\InnerWeaver.cs:line 144
at InnerWeaver.Execute() in c:\ConsoleBuildAgent\work\ed448661dbb30d2e\FodyIsolated\InnerWeaver.cs:line 62
Source:
Mono.Cecil
TargetSite:
Mono.Cecil.TypeReference TypeParameter(System.String, Int32)
I seems this is a generic problem with all methods returning generic tasks not know at build time of the library...
The problem is this code in ModuleWeavers.cs, AddAwaitConfigToAsyncMethod method:
if (v.VariableType.IsGenericInstance)
{
var genericVariableType = (GenericInstanceType)v.VariableType;
var variableType = v.VariableType.Resolve();
if (variableType.FullName == "System.Runtime.CompilerServices.TaskAwaiter`1")
v.VariableType = ModuleDefinition.ImportReference(gConfiguredTaskAwaiterTypeDef.MakeGenericInstanceType(genericVariableType.GenericArguments));
awaitableVar = new VariableDefinition(ModuleDefinition.ImportReference(gConfiguredTaskAwaitableTypeDef.MakeGenericInstanceType(genericVariableType.GenericArguments)));
method.Body.Variables.Insert(i + 1, awaitableVar);
var configureAwaitMethodDef = typeFinder.GetMSCorLibTypeDefinition("System.Threading.Tasks.Task`1").Methods.First(m => m.Name == "ConfigureAwait");
configureAwaitMethod = ModuleDefinition.ImportReference(configureAwaitMethodDef);
configureAwaitMethod.DeclaringType = ModuleDefinition.ImportReference(typeFinder.GetMSCorLibTypeDefinition("System.Threading.Tasks.Task`1").MakeGenericInstanceType(genericVariableType.GenericArguments));
}
It should be:
if (v.VariableType.IsGenericInstance)
{
var genericVariableType = (GenericInstanceType)v.VariableType;
var variableType = v.VariableType.Resolve();
if (variableType.FullName == "System.Runtime.CompilerServices.TaskAwaiter`1")
{
v.VariableType = ModuleDefinition.ImportReference(gConfiguredTaskAwaiterTypeDef.MakeGenericInstanceType(genericVariableType.GenericArguments));
awaitableVar = new VariableDefinition(ModuleDefinition.ImportReference(gConfiguredTaskAwaitableTypeDef.MakeGenericInstanceType(genericVariableType.GenericArguments)));
method.Body.Variables.Insert(i + 1, awaitableVar);
var configureAwaitMethodDef = typeFinder.GetMSCorLibTypeDefinition("System.Threading.Tasks.Task`1")
.Methods.First(m => m.Name == "ConfigureAwait");
configureAwaitMethod = ModuleDefinition.ImportReference(configureAwaitMethodDef);
configureAwaitMethod.DeclaringType = ModuleDefinition.ImportReference(typeFinder.GetMSCorLibTypeDefinition("System.Threading.Tasks.Task`1")
.MakeGenericInstanceType(genericVariableType.GenericArguments));
}
}
caesay has done a pull request that fixes this but the fix is entangled in a lot of other changes that distantcam may not be willing to take on board.
When I get a chance I will do a pull request with this fixed (and a unit test!)
Should be fixed in 0.3.0