-
Notifications
You must be signed in to change notification settings - Fork 35
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
Fix disposable extensions bugs and add relevant tests. #157
Conversation
TheSquidCombatant
commented
Mar 2, 2024
- Fixed error collection in DisposeAll method.
- Fixed thread blocking in DisposeAsync method.
- Added related tests in DisposableExtensionsTests class.
- Updated LangVersion option for use new csharp features.
Additional explanations and motivation
c1a0001#diff-f65ce38674f9332658a3ed2539215c062c082d789fae54abf0dd15cfcba27242L75
c1a0001#diff-f65ce38674f9332658a3ed2539215c062c082d789fae54abf0dd15cfcba27242L33
c1a0001#diff-138399ef9f53853c4f235de6ca89285ad9c2e84da0a4d8443847a466c19fbeb1R9 |
Additional refactoring and improvements
ca46ce8#diff-138399ef9f53853c4f235de6ca89285ad9c2e84da0a4d8443847a466c19fbeb1R64
ca46ce8#diff-f65ce38674f9332658a3ed2539215c062c082d789fae54abf0dd15cfcba27242L3
ca46ce8#diff-f65ce38674f9332658a3ed2539215c062c082d789fae54abf0dd15cfcba27242R69 |
There was a problem hiding this 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, LGTM !:)
disposable.Dispose(); | ||
return new ValueTask(); | ||
await asyncDisposable.DisposeAsync(); | ||
await new ValueTask(Task.Run(() => disposable.Dispose())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason for making ValueTask here?
Isn't await is enough ?
P.S.
Don't we need ConfigureAwaitable(false) as a library here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for the ValueTask - these two implementations have almost tame behavior so both look good for me.
ConfigureAwaitable is not used in the lib anyways. We may add the calls but I'm not sure if it should be done,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- +1
- At the moment, a lot of CJ code does not contain CfgAwait(false). If we move away from this, we should fix the whole library code.
The main idea behind this method is to call DisposeAsync if it is supported. And if it is not - call Dispose synchronously. The method, like much of CJ, is basically sugar, allowing you to avoid writing checks in the main code. |
@andrewvk, in my humble opinion, the |
Of course not. Asynchronous methods by default use the current synchronization context, which can be a little bit different (and that's why you sometimes need to insert ConfigureAwait(false)). Moreover, the official recommendations do not recommend using CfgAwait(false) in methods that take delegates as input, because the one who passes code expects that this code will be executed in the context in which the method with this parameter is called. |
We pass to the asynchronous Casting to the |
I think, I need to explain in more details the scenario for which this method was intended. There are situations when we have a collection of IDisposable (IAsyncDisposable has appeared relatively recently, and its adoption rate is not very high). However, some elements of the collection can still implement IAsyncDIsposable (but statically we don't know it!). This method allows you to run DisposeAsync, if any, without executing thread waiting for result. There was no idea to run regular Dispose in a separate thread, just as there was no idea to run DisposeAsync outside the current synchronization context. |
It was worth writing about this in the comment to |