Skip to content

Conversation

@MattKotsenas
Copy link
Member

@MattKotsenas MattKotsenas commented Jan 3, 2022

Fix #17217 by replacing non-generic collections classes with their generic counterparts. Of specific interest are:

  • The EditorTable related collections are public, and thus can't be converted without changing the public API
  • In a couple of places we have public APIs that return the Hashtable's enumerator, so we need to leave those as-is so the enumerated items are DictionaryEntry and not KeyValuePair
  • In places where the Hashtables were static, I verified that every use was either already under a lock, or switched to a ConcurrentDictionary to more closely match the Hashtable semantics of allowing multiple readers and a single writer

@ghost ghost added area-System.ComponentModel community-contribution Indicates that the PR has been added by a community member labels Jan 3, 2022
@ghost
Copy link

ghost commented Jan 3, 2022

Tagging subscribers to this area: @dotnet/area-system-componentmodel
See info in area-owners.md if you want to be subscribed.

Issue Details

Fix #17217 by replacing non-generic collections classes with their generic counterparts. Of specific interest are:

  • The EditorTable related collections are public, and thus can't be converted without changing the public API
  • Removal of the WeakHashtable in favor of the public ConditionalWeakTable
  • A change in binary formatting for the LicenseManager
Author: MattKotsenas
Assignees: -
Labels:

area-System.ComponentModel

Milestone: -

@stephentoub stephentoub added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Jan 4, 2022
@stephentoub
Copy link
Member

Thanks for working on this. I suggest scaling back the PR to just the replacements that are trivial to prove are correct. There are a myriad of functional and performance differences between what's being replaced and the replacements, and I'm concerned we'll find a number of regressions that slip through as a result.

@MattKotsenas
Copy link
Member Author

Thanks everyone for the feedback! I've pushed a less ambitious version that converts just two cases:

  • Private instance members that don't (at least appear to) have any multi-threading
  • Private statics where based on usage a ConcurrentDictionary looks appropriate

Additional feedback and thoughts are very welcome. My goal is less change for change's sake, and more to address the spirit of the linked issue (and hopefully close it out). If anyone has any thoughts, questions, or concerns, please let me know. Thanks!

Copy link
Contributor

@teo-tsirpanis teo-tsirpanis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static dictionaries that contain Type objects must be ConditionalWeakTables, not (Concurrent)Dictionaryies. Otherwise the types are rooted which inhibits unloadability and leads to bugs like #62050.

I have marked some places that should be changed, could you please do that? You can take advantage of the GetValue method; it works similarly to ConcurrentDictionary.GetOrAdd.

s_defaultAttributes is safe to change to CWT as well.

Edit: Oh, you had responded to a comment of mine. I thought you hadn't seen them.

@stephentoub
Copy link
Member

Static dictionaries that contain Type objects must be ConditionalWeakTables, not (Concurrent)Dictionaryies. Otherwise the types are rooted which inhibits unloadability and leads to bugs like #62050.

As long as this PR isn't adding additional rooting, I would prefer any changes to address concerns around unloadability be done separately in a dedicated PR.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @MattKotsenas.

Most of the files look fine. But 2 of them I'm not 100% sure are better. The 2 I tagged already have locking around modification, which we aren't changing the locking in this PR. I'm not sure we can trivially prove that changing from Hashtable to ConcurrentDictionary is beneficial. Can we revert those two files? We aren't actively investing in System.ComponentModel, and changes here would introduce more risk than the value these changes bring.

Other than that I think the rest of the changes are OK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I can trivially prove the changes in this file are correct. Can we revert this file's changes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I can trivially prove the changes in this file are correct. Can we revert this file's changes?

@eerhardt
Copy link
Member

@MattKotsenas - any response to my above feedback? If you aren't actively working on this PR, I can close it until it is active again.

@eerhardt eerhardt added the needs-author-action An issue or pull request that requires more info or actions from the author. label Jan 25, 2022
@MattKotsenas
Copy link
Member Author

Hi @eerhardt ! Yes, I'll back out those changes as well and update to resolve conflicts today or tomorrow. Thanks again for all the feedback!

@ghost ghost removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Jan 25, 2022
@MattKotsenas MattKotsenas force-pushed the refactor/17217-generics branch from 8e808ed to a04bc5c Compare January 26, 2022 18:10
@MattKotsenas MattKotsenas requested a review from eerhardt January 26, 2022 18:14
@MattKotsenas
Copy link
Member Author

@eerhardt updated! Please take a look when you get a chance and let me know if you have any thoughts / suggestions. Thanks!

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this slimmed down change is now fine. And with it we should be able to close the long-standing issue.

Thanks for the contribution, @MattKotsenas!

@stephentoub - I will wait for your approval before removing the "No Merge" label. Let me know what you think.

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Seems ok. All of those GetValueOrDefault calls are extension method calls resulting in virtual dispatch via IReadOnlyDictionary; it's probably ok given the library.

@stephentoub stephentoub removed the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Feb 8, 2022
@eerhardt
Copy link
Member

eerhardt commented Feb 8, 2022

Test failure is #64389. Merging.

@eerhardt eerhardt merged commit 826896f into dotnet:main Feb 8, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Mar 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.ComponentModel community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use generic collections in System.ComponentModel.TypeConverter implementation instead of non-generic

4 participants