-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unobserved Task Exception(s) around DependencyInjection.ServiceLookup.get_ServiceType() #37337
Comments
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.
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: I think the related PR that "broke" this is dotnet/extensions#2501 The reason why VS throws is that even so it's handled VS's default setting is to throw on NullRefernceException anyway. |
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: 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. 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. |
yes planning to port to 5.x as well. UPDATE: |
@maryamariyan : I have the same problem as @WolfspiritM when using IdentityServer, but i'm still using (Asp) .NetCore 3.1.10 currently. |
@BloodyMettle Are you maybe using the 5.0 nuget package for Microsoft.Extensions.DependencyInjection? It's not directly related to dotnet 5 but to the nuget package. |
@WolfspiritM Thanks - we are normally using 3.1.10 but to be sure I checked all dependencies again... one dependency was unintentionally installed with the latest version, resulting in a dependecy on 5.0 ... seems like this did the trick, my former comment can be ignored :) |
Description
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
Updated Information
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.
I also included another stack trace that includes line numbers in the code.
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.
Configuration
Regression?
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.
Other information
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.
The text was updated successfully, but these errors were encountered: