Since upgrading a large enterprise app from NetCore 3.2 to .Net 5.0 Preview 4, I am seeing an unobserved exception being rethrown by the finalizer. It happens several times repeatedly every time I run my application, but it occurs all over the place and I cannot seem to trace it to one specific cause. For the most part, my application does not crash and it continues to run without issue.
I say "for the most part" because I am seeing another odd problem (likely unrelated) where 50% of the time debugging under visual studio the app appears both my app and Visual Studio are unresponsive. I think all of my Tasks have Try/Catches around them but this project is at 149 libraries as of today so its hard to say for certain. (Update : I think my deadlock could be related to #35986 "AddHttpClient" where the DI container is suspect. My lock happens right around the time I would be requesting the Client from the container. Related or not, they share a common root.)
The Stack Trace is always the Same
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite.get_ServiceType()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstant(ConstantCallSite constantCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitNoCache(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(ServiceCallSite scopedCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(ServiceCallSite scopedCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(ServiceCallSite scopedCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.Build(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CompiledServiceProviderEngine.RealizeService(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>n__0(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__1()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__276_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
I had a chance to focus more on this issue and started by disabling "just my code". The first code block below shows that the internal class "ConstantCallSite" allows a Null value as the DefaultValue, but neither of the overrides for "ServiceType" nor "ImplementationType" check "DefaultValue" for null before accessing them.
internal class ConstantCallSite : ServiceCallSite
{
internal object DefaultValue { get; }
public ConstantCallSite(Type serviceType, object defaultValue): base(ResultCache.None)
{
if (defaultValue != null && !serviceType.IsInstanceOfType(defaultValue))
{
throw new ArgumentException(SR.Format(SR.ConstantCantBeConvertedToServiceType, defaultValue.GetType(), serviceType));
}
//If null is a valid value then the code should be updated to check for null before the overrides use it. If null is not a valid value
//then the parameter check statement above should be modified to throw, should it not? -JTB
DefaultValue = defaultValue;
}
public override Type ServiceType => DefaultValue.GetType();
public override Type ImplementationType => DefaultValue.GetType();
public override CallSiteKind Kind { get; } = CallSiteKind.Constant;
}
I also included another stack trace that includes line numbers in the code.
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite.ServiceType.get() Line 23
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ConstantCallSite.cs(23)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstant(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite constantCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 190
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(190)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 52
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(52)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 64
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(64)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 35
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(35)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 154
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(154)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 50
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(50)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, System.Reflection.Emit.ILGenerator generator) Line 361
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(361)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 105
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(105)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder..ctor.AnonymousMethod__12_0(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite cs) Line 62
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(62)
System.Collections.Concurrent.dll!System.Collections.Concurrent.ConcurrentDictionary<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod>.GetOrAdd<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite>(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod> valueFactory, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite factoryArgument) Line 1069
at /_/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs(1069)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 83
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(83)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite scopedCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 168
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(168)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 31
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(31)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 154
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(154)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 50
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(50)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, System.Reflection.Emit.ILGenerator generator) Line 361
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(361)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 105
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(105)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder..ctor.AnonymousMethod__12_0(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite cs) Line 62
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(62)
System.Collections.Concurrent.dll!System.Collections.Concurrent.ConcurrentDictionary<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod>.GetOrAdd<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite>(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod> valueFactory, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite factoryArgument) Line 1069
at /_/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs(1069)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 83
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(83)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite scopedCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 168
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(168)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 31
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(31)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 154
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(154)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 50
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(50)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, System.Reflection.Emit.ILGenerator generator) Line 361
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(361)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 105
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(105)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder..ctor.AnonymousMethod__12_0(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite cs) Line 62
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(62)
System.Collections.Concurrent.dll!System.Collections.Concurrent.ConcurrentDictionary<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod>.GetOrAdd<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite>(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod> valueFactory, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite factoryArgument) Line 1069
at /_/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs(1069)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 83
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(83)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.Build(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 74
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(74)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CompiledServiceProviderEngine.RealizeService(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 29
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CompiledServiceProviderEngine.cs(29)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.RealizeService.AnonymousMethod__1() Line 25
at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/DynamicServiceProviderEngine.cs(25)
System.Private.CoreLib.dll!System.Threading.Tasks.Task<System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, object>>.InnerInvoke() Line 498
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs(498)
System.Private.CoreLib.dll!System.Threading.Tasks.Task..cctor.AnonymousMethod__276_0(object obj) Line 2353
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2353)
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(System.Threading.Thread threadPoolThread, System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 289
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs(289)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot, System.Threading.Thread threadPoolThread) Line 2314
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2314)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteEntryUnsafe(System.Threading.Thread threadPoolThread) Line 2252
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2252)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteFromThreadPool(System.Threading.Thread threadPoolThread) Line 2237
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2237)
System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 659
at /_/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs(659)
System.Private.CoreLib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Line 29
at /_/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs(29)
I have an UnobservedTaskException handler catching this exception. The "sender" has the following information when I call "GetType()" using the Immediate Window in Visual Studio. My application continues to run regardless of me calling the SetObserved method on the UnobservedTaskExceptionEventArgs eventArgs object.
{Name = "Task`1" FullName = "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"}
Assembly: {System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e}
AssemblyQualifiedName: "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
Attributes: Public | BeforeFieldInit
BaseType: {Name = "Task" FullName = "System.Threading.Tasks.Task"}
Cache: {System.RuntimeType.RuntimeTypeCache}
CacheIfExists: {System.RuntimeType.RuntimeTypeCache}
ContainsGenericParameters: false
CustomAttributes: Count = 4
DeclaredConstructors: {System.Reflection.ConstructorInfo[15]}
DeclaredEvents: {System.Reflection.EventInfo[0]}
DeclaredFields: {System.Reflection.FieldInfo[2]}
DeclaredMembers: {System.Reflection.MemberInfo[60]}
DeclaredMethods: {System.Reflection.MethodInfo[37]}
DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22}
DeclaredProperties: {System.Reflection.PropertyInfo[5]}
DeclaringMethod: '((System.RuntimeType)senderType).DeclaringMethod' threw an exception of type 'System.InvalidOperationException'
DeclaringType: null
DomainInitialized: false
FullName: "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"
GUID: {56440075-ba51-37a6-9582-448a4f380bc0}
GenericCache: null
GenericParameterAttributes: '((System.RuntimeType)senderType).GenericParameterAttributes' threw an exception of type 'System.InvalidOperationException'
GenericParameterPosition: '((System.RuntimeType)senderType).GenericParameterPosition' threw an exception of type 'System.InvalidOperationException'
GenericTypeArguments: {System.Type[1]}
GenericTypeParameters: {System.Type[0]}
HasElementType: false
ImplementedInterfaces: {System.Type[2]}
IsAbstract: false
IsAnsiClass: true
IsArray: false
IsAutoClass: false
IsAutoLayout: true
IsByRef: false
IsByRefLike: false
IsCOMObject: false
IsClass: true
IsCollectible: false
IsConstructedGenericType: true
IsContextful: false
IsEnum: false
IsExplicitLayout: false
IsExportedToWindowsRuntime: false
IsGenericMethodParameter: false
IsGenericParameter: false
IsGenericType: true
IsGenericTypeDefinition: false
IsGenericTypeParameter: false
IsImport: false
IsInterface: false
IsLayoutSequential: false
IsMarshalByRef: false
IsNested: false
IsNestedAssembly: false
IsNestedFamANDAssem: false
IsNestedFamORAssem: false
IsNestedFamily: false
IsNestedPrivate: false
IsNestedPublic: false
IsNotPublic: false
IsPointer: false
IsPrimitive: false
IsPublic: true
IsSZArray: false
IsSealed: false
IsSecurityCritical: true
IsSecuritySafeCritical: false
IsSecurityTransparent: false
IsSerializable: false
IsSignatureType: false
IsSpecialName: false
IsTypeDefinition: false
IsUnicodeClass: false
IsValueType: false
IsVariableBoundArray: false
IsVisible: false
IsWindowsRuntimeObject: false
MemberType: TypeInfo
MetadataToken: 33555114
Module (System.Reflection.MemberInfo): {System.Private.CoreLib.dll}
Module: {System.Private.CoreLib.dll}
Name: "Task`1"
Namespace: "System.Threading.Tasks"
ReflectedType: null
StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
TypeHandle: {System.RuntimeTypeHandle}
TypeInitializer: {Void .cctor()}
UnderlyingSystemType: {Name = "Task`1" FullName = "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"}
m_cache: 0x1f399ea4
m_handle: 0x1ffbabb8
m_keepalive: null
I am 80% positive this did did not occur on .Net Core 3.2. I say 80% only because I have had so many distractions in my office lately that I could be mistaken when it began. Yet I know for a fact that I didn't notice it until I upgraded to .Net 5.0. I always run the app as an Exe (vs WinExe) so I have a console where I can see all of my logging live; thus I don't have to open a log file to be notified of the issue and am unlikely to overlook it.
The application is a point-of-sale touch-screen driven application with a pure MVVM architecture. It makes heavy use of Tasks and aysnc patterns where I am pretty anal about clean Task based coding such as no "async voids", no sync locking in async functions and etc. This is a complete ground-up re-write of an existing product so its currently all fresh code and plenty of mistakes are expected at this point; thus I could be doing something to cause this but from the looks of the stack trace it does not appear to be under my control.
If there is something special about my architecture that could agitate this bug it might be related to the hundreds of commands (ICommand) classes that are bound to buttons. I use a mediator pattern with a class that looks at an enum sent from the button press, maps that to an ICommand instance, probes the ICommand class to run the logic to see if it can be executed and based on that return value, it knows whether to execute the command synchronously or asynchronously. The majority of the commands are Task based. There is a lot of "awaiting" going on in this application and since it is also heavily dialog driven there can be more than one dispatcher thread running at times.
I will keep plugging away at this and update this report if I learn anything new.
I couldn't figure out the best area label to add to this issue. Please help me learn by adding exactly one area label.
I updated the issue with a second callstack that includes more useful information that I obtained after disabling "Just my Code".
Today I spent quite a bit more time tracking this issue down. Although the direct cause (other than the ConstantCallSite.DefaultValue null reference) is still alluding me, the following information may be useful.
In the hunt, I did some refactoring that would have changed task based timing. After this refactoring, I still hit the same type of exception, however it was then highly repeatable such that it happened on every boot at the exact same location unless I paused too long in the debugger, then it would not occur. The fact that I could hit it over and over again felt logical. Yet when I paused for a while, like 20 seconds, and then continued and did not hit the exception, I started to really get the feeling that this is timing related or maybe even interference from Visual Studio??
This time I tracked the issue down to a Transitive, Optional Constructor injected dependency that I did not provide an implementation for. However the DI container was throwing an exception, hitting that same null reference in the ConstantCallSite class unless I removed the optional parameter or gave the DI container an implementation for it. Note that when I initially reported this issue above, the container couldn't have been throwing the unobserved Task exception from this location because I was using that class to fetch my apps data. It was really hard to track it down when I first reported the issue because it was hitting the unobserved Task exception. After changing the code slightly it was more repeatable yet in a different manner.
Using the example below, I would add both class A and class B to the services collection, build the container and then request an instance of class A. I really don't know if this issue has anything at all to do with transitive dependencies but I included that fact since that was the reality of the situation. Note that after I narrowed this down, I created a small sample project to share BUT I couldn't reproduce the same error in the sample project. I did not kick off Tasks in the sample project and probably should have but I am really pressed for time and debugging the DI container is something I wish I could help with but I must focus on my own work.
public class A
{
public B B {get;}
public A(B b)
{
B = b;
}
}
public class B
{
public Optional Optional {get;}
public B(Optional? optional = null)
{
//The DI container would not provide me with an instance of class B unless
//I paused at the debugger for a while, OR I removed the optional parameter
}
}
If the ConstantCallSite.DefaultValue is updated to either throw an exception inside the constructor if null OR if null is a valid value then check it before dereferencing it, it might add a touch more clarity on this problem. However, I suspect the primary cause is elsewhere. It seems to be a timing issue. If I learn anything else I will update. For now, I am just going to provide an implementation for that optional parameter and hope that other timing changes do not cause the bug to show itself again.
Could you possibly send a reproducible project that we could clone and reproduce and if not, maybe you could consider sharing it privately. Because without reproducible code it would be hard to verify the problem/provide a fix.
@maryamariyan It's been 3 months since I posted this :). I think that any software engineer could look at the extremely detailed information above and create a simple project from it. I included sample code classes in the details and even pointed Microsoft at the exact line of their code that needs to be corrected.
I like to try and help out but I also have plenty work of my own to do. I'm pretty confident in the Microsoft engineers and for that reason I'm sure they will know exactly what I am talking about. If not we have other problems.
I'm having the same issue with an Aspnet Core application. I tried upgrading it from 3.1 to 5.0 and now visual studio throws exceptions when accessing certain controllers.
I tracked it down to the same problem which is a constructor for a transient service that expects an interface that I did not register but it has a default value set (null).
EDIT:
After testing even more I now found a very easy way to reproduce it:
https://gist.github.com/WolfspiritM/e16eb78772bca2856799ef17277bc117
I think the related PR that "broke" this is https://github.com/dotnet/extensions/pull/2501
The reason why VS throws is that even so it's handled VS's default setting is to throw on NullRefernceException anyway.
I think it should be fixed cause it prevents code optimization via the ILEmitter
I am also having this issue with my Blazor Hosted WebAssembly app. it's using Identity Server and occurs after sign-in. Strange thing is that sign-in works perfectly the first time I get this error only after signing-out then signing-in again. Same thing null value in ConstantCallSite.DefaultValue. If I hit continue when the exception is thrown login proceeds as excepted. Further sign-in and sign-outs do not cause this error. Seems to be happening only the second time for me.
@Gannond0rf Yep. The issue hit me with IdentityServer aswell. The reason is acutally this class of IdentityServer:
https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/OidcReturnUrlParser.cs
(notice the IAuthorizationParametersMessageStore authorizationParametersMessageStore = null in the constructor)
When it creates an instance of:
https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/DefaultIdentityServerInteractionService.cs which is used probably in an AccountService (for login/logoff) via IIdentityServerInteractionService.
As far as I understand the reason why it happens the second time is that on the second resolve of a service the DI Framework creates an optimized "path" to create the service (via a background worker) and stores that optimized version. This creation fails with a NullReferenceException and is actually caught via a try catch to swallow any exception. Every further resolving just uses the unoptimized version as the optimized version is never available.
Visual Studio per default has NullReferenceExceptions set to be thrown even so they're handled.
My workaround for now is to disable NullReferenceExceptions via Debug -> Windows -> Exception Settings -> Common Language Runtime Exceptions and I hope it's fixed soon.
Probably it also works to provide an instance of IAuthorizationParametersMessageStore.
@WolfspiritM thanks for the info, much appreciated. At least now I know it's not a problem with my project.
@maryamariyan Will this be merged into 5.x? As the milestone says 6.0? I'd rather not want to keep the null reference in VS unchecked the whole year.
@maryamariyan Will this be merged into 5.x? As the milestone says 6.0? I'd rather not want to keep the null reference in VS unchecked the whole year.
yes planning to port to 5.x as well.
UPDATE:
Refer to PR https://github.com/dotnet/runtime/pull/44877
Most helpful comment
@Gannond0rf Yep. The issue hit me with IdentityServer aswell. The reason is acutally this class of IdentityServer:
https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/OidcReturnUrlParser.cs
(notice the
IAuthorizationParametersMessageStore authorizationParametersMessageStore = nullin the constructor)When it creates an instance of:
https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/DefaultIdentityServerInteractionService.cs which is used probably in an AccountService (for login/logoff) via IIdentityServerInteractionService.
As far as I understand the reason why it happens the second time is that on the second resolve of a service the DI Framework creates an optimized "path" to create the service (via a background worker) and stores that optimized version. This creation fails with a NullReferenceException and is actually caught via a try catch to swallow any exception. Every further resolving just uses the unoptimized version as the optimized version is never available.
Visual Studio per default has NullReferenceExceptions set to be thrown even so they're handled.
My workaround for now is to disable NullReferenceExceptions via Debug -> Windows -> Exception Settings -> Common Language Runtime Exceptions and I hope it's fixed soon.
Probably it also works to provide an instance of IAuthorizationParametersMessageStore.