Skip to content

Conversation

ShreyasJejurkar
Copy link
Contributor

  1. Another fix - Removed unwanted variable was added as part of Stop the host first and then dispose it! #29404

Fixes #29455

1. Other fix - Removed unwanted variable was added as part of #29404

Fixes #29455
@ghost ghost added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jan 20, 2021
Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

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

Looks great!

Thanks for taking care of this so quick!

@javiercn javiercn added the community-contribution Indicates that the PR has been added by a community member label Jan 20, 2021
@ShreyasJejurkar
Copy link
Contributor Author

@javiercn My pleasure!

@pranavkm pranavkm added the api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews label Jan 20, 2021
@ghost
Copy link

ghost commented Jan 20, 2021

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

Base automatically changed from master to main January 22, 2021 01:33
@javiercn
Copy link
Member

/AzurePipelines run AspNetCore-ci

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources asynchronously
/// </summary>
protected virtual async ValueTask DisposeAsyncCore()
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't need to add this API. I think it's sufficient to explicitly implement IAsyncDisposable in derived class and call base.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean, I should remove this method?

Copy link
Member

Choose a reason for hiding this comment

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

Yes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But then dispose will be synchronous! Because public method DisposeAsync() will call sync version of dispose on line 538.

Copy link
Contributor Author

@ShreyasJejurkar ShreyasJejurkar Feb 20, 2021

Choose a reason for hiding this comment

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

@pranavkm I have removed DisposeAsyncCore() method in the latest commit. But right now DisposeAsync() method calling the synchronous version of Dispose() under the hood, isn't that wrong? Or am I missing something here to understand!
Thanks!

@pranavkm pranavkm added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels Feb 1, 2021
@javiercn
Copy link
Member

Coming back to this, I think the pattern should be something like this, based on:

The main points are:

  • Dispose(bool) always disposes things that implement IDisposable when disposing = true and just releases unmanaged resources otherwise.
  • Dispose(bool) disposes async resources and blocks if Dispose() was invoked instead of DisposeAsync()
    • This can likely be pushed to Dispose() however derived classes should call base.Dispose(disposing)
  • DisposeAsync invokes DisposeAsyncCore to dispose IAsyncDisposable values, sets a flag for Dispose(disposing) to avoid invoking DisposeAsyncCore and blocking, calls Dispose(disposing: true) and then `GC.SupressFinalize(this).
  • The finalizer only releases unmanaged resources for which there are no asynchronous versions.

@davidfowl thoughts?

public class MyClass : IDisposable, IAsyncDisposable
{
    private bool _disposed = false;
    private bool _disposeAsync = false;

    public void Dispose()
    {
        if(_disposed)
        {
            return;
        }

        Dispose(disposing: true);
        GC.SupressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if(disposing)
        {
            if(!_disposeAsync)
            {
                DisposeAsyncCore()
                    .ConfigureAwait(false)
                    .GetAwaiter()
                    .GetResult();
            }
        }

        // Release unmanaged resources
    }

    public virtual ValueTask DisposeAsyncCore() => return default;

    public ValueTask DisposeAsync()
    {
        if(_disposed)
        {
            return;
        }
        if(_disposeAsync)
        {
            return;
        }
        _disposed = true;

        await DisposeAsyncCore().ConfigureAwait(false);
        _disposeAsync = true;
        
        Dispose(disposing: true);
        GC.SupressFinalize(this);
    }

    ~MyClass
    {
        Dispose(disposing: false);
    }
}

@javiercn javiercn added the pr: pending author input For automation. Specifically separate from Needs: Author Feedback label Apr 19, 2021
public ValueTask DisposeAsync()
{
Dispose(disposing: false);
GC.SuppressFinalize(this);
Copy link
Member

Choose a reason for hiding this comment

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

Remove this, there's no finalizer.

/// <inheritdoc />
public ValueTask DisposeAsync()
{
Dispose(disposing: false);
Copy link
Member

Choose a reason for hiding this comment

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

We want to actually call DisposeAsync on the host.

public async Task TestingInfrastructure_GenericHost_HostDisposeAsync()
{
// Act
await using var factory = new CustomizedFactory<GenericHostWebSite.Startup>();
Copy link
Member

Choose a reason for hiding this comment

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

Make sure this adds a service that is only IAsyncDisposable, that's the real test.

@ghost
Copy link

ghost commented Apr 29, 2021

Hi @MCCshreyas.
It seems you haven't touched this PR for the last two weeks. To avoid accumulating old PRs, we're marking it as stale. As a result, it will be closed if no further activity occurs within 4 days of this comment. You can learn more about our Issue Management Policies here.

@ghost ghost added the stale Indicates a stale issue. These issues will be closed automatically soon. label Apr 29, 2021
@ghost ghost closed this May 3, 2021
@HEskandari HEskandari mentioned this pull request May 13, 2021
4 tasks
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved API was approved in API review, it can be implemented area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates community-contribution Indicates that the PR has been added by a community member pr: pending author input For automation. Specifically separate from Needs: Author Feedback stale Indicates a stale issue. These issues will be closed automatically soon.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Mvc] WebApplicationFactory should implement IAsyncDisposable
4 participants