-
Notifications
You must be signed in to change notification settings - Fork 780
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
Make use of more performant System.Threading.Lock where possible #2501
base: master
Are you sure you want to change the base?
Conversation
Hi. I like the idea, but I don't want to add a NuGet dependency for this. I'd rather have an internal Lock type in the Shared folder that projects reference. Or perhaps just add a using alias for it: #if !NET9_OR_GREATER
using Lock = System.Object;
#endif |
The problem is that some things won't compile properly that way, such as this code: Debug.Assert(Lock.IsHeldByCurrentThread); |
I dropped the dependency, just giving some credit to the package in comments. What do you think? |
Does |
It's not the proper way to use it now but I have no idea. Will try it tomorrow. |
I don't want to update source code to not use the lock statement. And I don't want to add a new package. My preference is to have .NET 9 (and later) targets use the new lock type, and older targets to keep using object. To be honest I don't think there will be any noticeable difference in performance, none of the locks a very contented, so it's fine if just future runtimes get any benefit. If internal static class CompatibilityHelpers
{
#if NET9_OR_GREATER
public static bool IsLockHeldByCurrentThread(Lock lock) => lock.IsHeldByCurrentThread;
#else
public static bool IsLockHeldByCurrentThread(object lock) => Monitor.IsEntered(lock);
#endif
}
// usage
Debug.Assert(CompatibilityHelpers.IsLockHeldByCurrentThread(Lock)); |
I already updated the code to drop the dependency. It's not going to be possible to use every feature of the new lock class and have the same code compile for .NET 8 or earlier. The aim is to make it close enough, because then the alternative is using preprocessor directives and it all starts getting messy. The problem where I stopped using locks was when used inside async methods. Even though a lock on an object would work when inside it there's no async calls, for some reason the lock on this fake lock object doesn't and I haven't figured out why and whether or not it can be fixed. To be honest if those locks are set back to an object it would be OK but then you end up with a mix of some sync locks using object and others using Lock. |
Ah gotcha! This is going to be the new reality moving forward and nothing to do with the backport code in fact but rather with C# 13. That is, you will have this issue even if you only target .NET 9.0. If you're using the new System.Threading.Lock class, you can't lock on it in an async method, even if you're not awaiting anything inside (CS9217). Even if you try to convert it to an object, it will give warning CS9216. |
@JamesNK a new version of Backport.System.Threading.Lock has come out that acts as a source generator and basically dropping the DLL as a dependency. If this new development makes you reconsider, I will amend this PR accordingly. |
No description provided.