Skip to content

Implement DisconnectAsync method in SocketTaskExtensions #1608

@gacardinal

Description

@gacardinal

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions