-
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
Unable to delete unloaded dll after using System.Text.Json.JsonSerializer.Serialize with a Type from the dll. #80420
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue DetailsDescriptionAfter creating a new AssemblyLoadContext and loading in a dll to it, I make use of the new types if they are deriving from specific base classes in our project. As a result, I end up doing json serialization for some of these types, however after I have done that, I'm no longer able to delete the dll after unloading it. Reproduction Stepshttps://github.com/frederik5480/HangingReferenceExample/tree/main/HangingReferenceExample This is a small console app that enables 4 endpoints to show a trimmed down usecase. The app is simple, as it's a small API listening on 4 specific endpoints. However, the issue comes up when doing serialization of the object. Expected behaviorThe expected behaviour in this case would be that I would be allowed to delete the dll file, as the assembly was unloaded without issues, I would expect no references to be kept. Actual behaviorTheres references being cached somewhere that's inaccessible for me to get to and clear, resulting in the removal of the dll file being impossible, no matter how long I wait, the GC doesn't clear them either, so the application has to be recycled before the dll can be removed, which is not ideal. Regression?No response Known WorkaroundsNot an ideal workaround, but a list of dll names can be stored somewhere and removed when the application recycles. ConfigurationNo response Other informationNo response
|
Duplicate of #65323. |
Description
After creating a new AssemblyLoadContext and loading in a dll to it, I make use of the new types if they are deriving from specific base classes in our project. As a result, I end up doing json serialization for some of these types, however after I have done that, I'm no longer able to delete the dll after unloading it.
If I choose to simply just unload it without doing any serialization, I can delete the file as expected.
As a note, this happens in multiple other scenarios as well, such as MVC Modelbinding (when I use TryUpdateModel) and simply just when a response in a custom controller is of one of these types in the dll. (Minor note that Newtonsoft also gives us the same problem)
From what I can tell there's various caches that caches the Types, however I have no way of clearing these for when I want to unload and delete the dll.
It's also worth noting that the unloading happens just fine and the AssemblyLoadContext is gone, I am also able to load in the same dll (or an updated version) and access the types again after that, while after unloading it it's unaccessible, I simply cant remove the file.
Reproduction Steps
https://github.com/frederik5480/HangingReferenceExample/tree/main/HangingReferenceExample
This is a small console app that enables 4 endpoints to show a trimmed down usecase.
Firstly the 'HangingReferenceExample' project needs to be built, as it has the base class used by the library.
Then the 'GithubExample' needs to be built - this of course results in a GithubExample.dll file, which needs to be moved into the bin folder of the 'HangingReferenceExample' project.
Now the 'HangingReferenceExample' needs to be started.
The app is simple, as it's a small API listening on 4 specific endpoints.
As by default the 'GithubExample' dll is not loaded in, we do that by calling GET 'http://localhost:8080/Load'
Now we should be able to access the types in the dll, so we can call GET 'http://localhost:8080/TestToString' and get a response.
This response is simply just accessing the model from the dll and calling .ToString() on it, to prove that we have accessed it.
We can now call GET 'http://localhost:8080/Unload', which should successfully unload the dll, and we can even enter the /bin directory and successfully delete the dll file.
However, the issue comes up when doing serialization of the object.
So if we repeat the first step of calling GET 'http://localhost:8080/Load'
Now if we call the 4th endpoint, GET 'http://localhost:8080/TestToJson' it will do a serialization of the object and return that, so we should see a JSON response.
If we now continue and call GET 'http://localhost:8080/Unload', it should unload successfully.
However entering the /bin directory, we will now be unable to delete the dll file, as a reference is still kept somewhere.
Expected behavior
The expected behaviour in this case would be that I would be allowed to delete the dll file, as the assembly was unloaded without issues, I would expect no references to be kept.
However since that's not the case, I would like to be enlightened on how the actual expectation for this is, as it's a problem in multiple places, not just JSON serialization.
Actual behavior
Theres references being cached somewhere that's inaccessible for me to get to and clear, resulting in the removal of the dll file being impossible, no matter how long I wait, the GC doesn't clear them either, so the application has to be recycled before the dll can be removed, which is not ideal.
Regression?
No response
Known Workarounds
Not an ideal workaround, but a list of dll names can be stored somewhere and removed when the application recycles.
This works because the AssemblyLoadContext is being unloaded, so a new one with the same dll can be loaded in again and then accessed. I have not found any issue with types clashing in these caches when I upload new versions (or just edited models) in the dlls, but I can't say for sure that it's the case for all the places this caching occurs.
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: