Skip to content
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

Implement DisconnectAsync method in SocketTaskExtensions #1608

Closed
gacardinal opened this issue Jan 10, 2020 · 6 comments · Fixed by #51213
Closed

Implement DisconnectAsync method in SocketTaskExtensions #1608

gacardinal opened this issue Jan 10, 2020 · 6 comments · Fixed by #51213
Labels
api-approved API was approved in API review, it can be implemented area-System.Net.Sockets
Milestone

Comments

@gacardinal
Copy link

gacardinal commented Jan 10, 2020

I was using the Socket extension methods provided by the SocketTaskExtensions class in System.Net.Sockets and noticed that almost all the *Async methods from Socket that are IO bound operations seemed to have their Task returning counterpart in SocketTaskExtensions except for DisconnectAsync.

Now, I've asked around online and people seemed to have mixed feelings about the issue. Some people didn't seem to understand why one would want to wait for the IO to complete when disconnecting a Socket. It's true that in most cases it's not really useful (and as I understand it, it's probably the reason it's not yet implemented in the framework) but even if use cases are limited, I would make the argument that for the sake of consistency, it'd be better that the SocketTaskExtensions class provides a DisconnectAsync method.

Implementation

My proposition is to add a DisconnectAsync method to the SocketTaskExtensions class.

    public static class SocketTaskExtensions
    {
        // ...
        public static Task DisconnectAsync(this Socket that, bool reuseSocket)
    }

The task is intentionally not returning a bool as its result (like the Socket.DisconnectAsync() is returning a bool to indicate whether the operation completed synchronously or not) because the goal of this extension method is to abstract that away.

Usage

A developer could use the API in the following way

    class Program
    {
        static async Task Main(string[] args)
        {
            Socket dummyReceiver = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            dummyReceiver.Bind(new IPEndPoint(IPAddress.Loopback, 7777));
            dummyReceiver.Listen(1);
            
            await Task.Run(() => {
                dummyReceiver.AcceptAsync();
                byte[] buffer = new byte[1000];
                dummyReceiver.ReceiveAsync(buffer, new SocketFlags());
            });

            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            s.Connect(new IPEndPoint(IPAddress.Loopback, 7777));

            await s.SendAsync(new byte[10000], new SocketFlags());
            await s.DisconnectAsync(false);
        }
    }

Additional context

Just to add some additional context, what led to me making this PR is this Stack Overflow question.

I would be happy to contribute an implementation for this feature!

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net.Sockets untriaged New issue has not been triaged by the area owner labels Jan 10, 2020
@scalablecory scalablecory added api-suggestion Early API idea and discussion, it is NOT ready for implementation and removed untriaged New issue has not been triaged by the area owner labels Jan 10, 2020
@scalablecory scalablecory added this to the Future milestone Jan 14, 2020
@karelz karelz added the untriaged New issue has not been triaged by the area owner label Feb 20, 2020
@karelz
Copy link
Member

karelz commented Feb 20, 2020

Triage: We already have BeginDisconnect, so adding DisconnectAsync makes sense. Low pri.

@karelz karelz removed the untriaged New issue has not been triaged by the area owner label Feb 20, 2020
@scalablecory
Copy link
Contributor

Duplicate of #33417. Not really (using Github keyword) -- just consolidating socket API proposals to streamline for focused API review.

@geoffkizer
Copy link
Contributor

I'm going to reopen this so we can do API review specifically on this (as opposed to all the APIs in #33417).

Also we should add a CancellationToken.

Updated proposal:

    public static class SocketTaskExtensions
    {
        // Existing APIs:
        // public IAsyncResult BeginDisconnect (bool reuseSocket, AsyncCallback callback, object state);
        // public void EndDisconnect (IAsyncResult asyncResult);

        public static Task DisconnectAsync(this Socket that, bool reuseSocket, CancellationToken cancellationToken);
    }

@geoffkizer geoffkizer reopened this Oct 26, 2020
@geoffkizer geoffkizer modified the milestones: 5.0.0, 6.0.0 Oct 26, 2020
@geoffkizer geoffkizer added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Oct 26, 2020
@terrajobst terrajobst added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Oct 27, 2020
@terrajobst
Copy link
Member

terrajobst commented Oct 27, 2020

Video

  • Looks good as proposed
  • We should really consider "removing" SocketTaskExtensions
    • Merge with instance methods
    • Hide type & member
    • If we do this for .NET 6, we should delete DisconnectAsync from this type
    • @geoffkizer, could you file an issue for this?
  • We should use ValueTask
namespace System.Net.Sockets
{
    public static class SocketTaskExtensions
    {
        // Existing APIs:
        // public IAsyncResult BeginDisconnect (bool reuseSocket, AsyncCallback callback, object state);
        // public void EndDisconnect (IAsyncResult asyncResult);

        public static ValueTask DisconnectAsync(this Socket socket, bool reuseSocket, CancellationToken cancellationToken=default);
    }
}

@geoffkizer
Copy link
Contributor

We should really consider "removing" SocketTaskExtensions

Added #43901

@geoffkizer
Copy link
Contributor

Note, per approval of #43901, this should be added as an instance method and not added to SocketTaskExtensions.

namespace System.Net.Sockets
{
    public partial class Socket
    {
        public ValueTask DisconnectAsync(bool reuseSocket, CancellationToken cancellationToken=default);
    }
}

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jan 13, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Feb 16, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Apr 14, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Apr 18, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Net.Sockets
Projects
None yet
6 participants