-
-
Notifications
You must be signed in to change notification settings - Fork 887
Fixed Issue#1628 #1629
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
Fixed Issue#1628 #1629
Conversation
…- it is done at public method calls
… was disposed, check is delegated to public methods using that property
…having a Finalization method
internal call EnsureNotDisposed is no longer virtual -> micro speedup gain in pixel index accessor Image<TPixel>[x, y].
As Image does not have unmanaged resources and does not implement finalizer method, there's no need for disposable pattern with a pair of Dispose() & Dispose(bool). Due Dispose(bool) was changed to DisposeManaged().
Subject to discuss. Image public properties Height, Width, Metadata and PixelType can't corrupt anything if backing image was disposed so I don't see any point altering that behaviour, it wasn't throwing before this branch and shouldn't throw after.
…ensures all operations are called on valid object
… if object was disposed
Codecov Report
@@ Coverage Diff @@
## master #1629 +/- ##
==========================================
+ Coverage 84.12% 84.15% +0.02%
==========================================
Files 812 812
Lines 35592 35634 +42
Branches 4146 4147 +1
==========================================
+ Hits 29943 29987 +44
Misses 4831 4831
+ Partials 818 816 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
|
I'll get this reviewed ASAP. Thanks for the contribution! |
JimBobSquarePants
left a comment
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.
Definitely the right direction but we need to fix up the Disposal pattern changes to match convention and prevent breaking the API.
src/ImageSharp/Image.cs
Outdated
| /// </summary> | ||
| /// <param name="disposing">Whether to dispose of managed and unmanaged objects.</param> | ||
| protected abstract void Dispose(bool disposing); | ||
| protected abstract void DisposeManaged(); |
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.
This breaks common convention and the API so I can't allow it.
Providing an abstract protected abstract void Dispose(bool disposing) is well documented and should be the pattern we use.
| public void Save_ObjectDisposedException() | ||
| { | ||
| var image = new Image<Rgba32>(this.configuration, 10, 10); | ||
| var stream = new MemoryStream(); |
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.
using stream. The fact that the GC cleans up here is an implementation detail.
src/ImageSharp/Image.cs
Outdated
| { | ||
| if (this.isDisposed) | ||
| { | ||
| throw new ObjectDisposedException("Trying to execute an operation on a disposed image."); |
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.
We should be using a ThrowHelper here to allow inlining on sealed instances.
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.
You mean ThrowHelper class from ThrowHelper.cs? Should I add ThrowArgumentException method or am I missing something? (there is none as far as I can see :P)
| /// that make up an <see cref="Image"/>. | ||
| /// </summary> | ||
| public abstract class ImageFrameCollection : IEnumerable<ImageFrame> | ||
| public abstract class ImageFrameCollection : IDisposable, IEnumerable<ImageFrame> |
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.
Wow. I hadn't realized this wasn't already implementing the type. Good catch!
| public void Dispose() | ||
| { | ||
| this.Dispose(true); | ||
| GC.SuppressFinalize(this); |
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.
We shouldn't be removing the finalizer suppression in the base class.
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.
Didn't know SuppressFinalize do nothing if type has no finalizer, thanks!
src/ImageSharp/Image{TPixel}.cs
Outdated
| throw new ObjectDisposedException("Trying to execute an operation on a disposed image."); | ||
| } | ||
| } | ||
| protected override void DisposeManaged() => this.frames.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.
The original pattern was correct here.
…d raw throws with this in Image/ImageFrameCollection
|
@JimBobSquarePants seems like I've messed up with ThrowHelper from shared infrastructure. Although I'd added it locally, I've totally missed that it wasn't in the commit and it isn't tracked by git now. How to fix it? |
Not at all!! You're contributions are most welcome! That's my mistake for not being clear. |
|
Got it, thanks for answering yet another question! |
|
@br3aker Can you please give me write access to your fork. For some reason I'm unable to push directly to your PR so we can complete this. |
|
@JimBobSquarePants that's strange. Edit was enabled from the start, I re-checked it now, can you try it again please? |
|
@br3aker This isn't the first PR I've had issues with and I'm not sure why it happens. I tried again and it didn't work. The last time the contributor had to explicitly invite me as a contributor to the repo as a workaround. |
|
@JimBobSquarePants invite sent, thanks for fixing this! |
JimBobSquarePants
left a comment
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.
LGTM 👍 Thanks!
Prerequisites
Description
Fixes #1628
Some public properties can't break anything (e.g image size or metadata), they didn't throw before this PR, this behaviour wasn't altered.
ToStringweren't affected either.Due to slight internal (within
Imageclass) API change pixel indexer might be a bit more performant:EnsureNotDisposed()call is no longer virtual. Although JIT in some runtimes even could inline such virtual calls in previous versions, it's still a nice change of having one less virtual method I guess.This change also affects any public method but their calls are too rare to affect performance.