Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 2, 2025

Implementation Complete: Obsolete NamedPipeClientStream constructor with isConnected parameter (SYSLIB0063)

Summary of Changes

This PR implements the approved API proposal to obsolete the NamedPipeClientStream constructor that takes a bool isConnected parameter, and introduces a new constructor without it.

Changes Made:

  • Added SYSLIB0063 diagnostic to Obsoletions.cs with appropriate message
  • Added new constructor NamedPipeClientStream(PipeDirection, bool, SafePipeHandle) that always sets state to Connected
  • Marked existing constructor with [Obsolete] and [EditorBrowsable(EditorBrowsableState.Never)] attributes
  • Obsolete constructor now calls new constructor to avoid code duplication
  • Updated ref assembly with both constructors and appropriate attributes
  • Updated documentation in list-of-diagnostics.md
  • Tests cover new constructor only to avoid duplication (obsolete ctor delegates to new one)
  • Added test to verify Connect and ConnectAsync throw InvalidOperationException on pipes created from existing handles
  • Build verification: All libraries build successfully
  • Test verification: All 1,161 System.IO.Pipes tests pass (0 failures)

API Changes:

namespace System.IO.Pipes;

public sealed partial class NamedPipeClientStream : PipeStream
{
    // Obsoleted constructor (existing) - now delegates to new constructor
    [EditorBrowsable(EditorBrowsableState.Never)]
    [Obsolete("This constructor has been deprecated and argument bool isConnected does not have any effect. Use NamedPipeClientStream(PipeDirection direction, bool isAsync, SafePipeHandle safePipeHandle) instead.", DiagnosticId = "SYSLIB0063", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
    public NamedPipeClientStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle);

    // New recommended constructor
    public NamedPipeClientStream(PipeDirection direction, bool isAsync, SafePipeHandle safePipeHandle);
}

Compatibility:

  • The obsolete constructor remains functional but issues a compile-time warning (SYSLIB0063)
  • The isConnected parameter is now ignored by delegating to the new constructor
  • New code should use the 3-parameter constructor which always sets the pipe to Connected state
  • This follows .NET obsoletion best practices with EditorBrowsable to hide from IntelliSense
  • Calling Connect/ConnectAsync on a pipe created from an existing handle now consistently throws InvalidOperationException (regardless of the isConnected parameter value in the obsolete constructor)
Original prompt

This section details on the original issue you should resolve

<issue_title>[API Proposal]: Hide NamedPipeClientStream ctor with isConnected argument</issue_title>
<issue_description>### Background and motivation

As described by #32760 (comment), the constructor

public NamedPipeClientStream(System.IO.Pipes.PipeDirection direction, bool isAsync, bool isConnected, Microsoft.Win32.SafeHandles.SafePipeHandle safePipeHandle)

Using isConnected: false is invalid, it will throw an exception when Connect is called because it requires a path to establish the connection. We should discourage the use of this ctor and instead suggest using a new ctor that doesn't take bool isConnected.

To preserve compatibility in the existing ctor, I think we should ignore isConnected rather than throwing.

Related:
#32760
#83073

API Proposal

namespace System.IO.Pipes;

public sealed partial class NamedPipeClientStream : PipeStream
{
+   [EditorBrowsable(EditorBrowsableState.Never)]
+   [Obsolete("This constructor has been deprecated and argument bool isConnected does not have any effect. Use NamedPipeClientStream(PipeDirection direction, bool isAsync, SafePipeHandle safePipeHandle) instead.")]
    public NamedPipeClientStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle) : base (default(PipeDirection), default(int)) { }

+   public NamedPipeClientStream(PipeDirection direction, bool isAsync, SafePipeHandle safePipeHandle) : base(default(PipeDirection), default(int)) { }
}

Alternative Designs

None that I can think of, but I considered fixing the issue by using the provided handle to reconnect to the named pipe server. That doesn't seem feasible, A client Connects by obtaining a handle (via CreateFile in Windows and via Socket.Connect on Unix). reconnecting would imply discarding the existing handle.

Risks

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

@bartonjs [Video](https://www.youtube.com/watch?v=rsjimPqjyDY&t=1h16m47s)
  • Given that we can find very few callers of this constructor, and isConnected: false doesn't seem to make sense, Obsolete+EB-Never makes sense.
  • Use the next available SYSLIB diagnostic ID.
namespace System.IO.Pipes;

public sealed partial class NamedPipeClientStream : PipeStream
{
+   [EditorBrowsable(EditorBrowsableState.Never)]
+   [Obsolete("This constructor has been deprecated and argument bool isConnected does not have any effect. Use NamedPipeClientStream(PipeDirection direction, bool isAsync, SafePipeHandle safePipeHandle) instead.")]
    public NamedPipeClientStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle) : base (default(PipeDirection), default(int)) { }

+   public NamedPipeClientStream(PipeDirection direction, bool isAsync, SafePipeHandle safePipeHandle) : base(default(PipeDirection), default(int)) { }
}
```</body></comment_new>
</comments>
Fixes #119671

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

… (SYSLIB0063)

Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] [API Proposal]: Hide NamedPipeClientStream ctor with isConnected argument Obsolete NamedPipeClientStream constructor with isConnected parameter (SYSLIB0063) Oct 2, 2025
@Copilot Copilot AI requested a review from jozkee October 2, 2025 15:46
Copilot finished work on behalf of jozkee October 2, 2025 15:46
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

@jozkee jozkee marked this pull request as ready for review October 16, 2025 15:25
@jozkee jozkee requested a review from jeffhandley as a code owner October 16, 2025 15:25
@Copilot Copilot AI review requested due to automatic review settings October 16, 2025 15:25
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR obsoletes the NamedPipeClientStream constructor that takes a bool isConnected parameter (as it's effectively meaningless) and introduces a new constructor without this parameter. The isConnected parameter only ever had one valid value (true), making it redundant and confusing.

Key changes:

  • Introduces diagnostic ID SYSLIB0063 for the obsolete constructor
  • Adds a new constructor without the isConnected parameter that always sets the connection state to Connected
  • Updates existing tests to use the new constructor or suppress the obsolete warning where necessary

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs Adds the new constructor and marks the old one as obsolete with SYSLIB0063
src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs Updates reference assembly with new constructor and obsolete attribute
src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj Links Obsoletions.cs to the project
src/libraries/Common/src/System/Obsoletions.cs Defines SYSLIB0063 diagnostic ID and message
docs/project/list-of-diagnostics.md Documents the new SYSLIB0063 diagnostic
src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CreateClient.cs Adds tests for the new constructor and updates existing tests with pragma warnings
src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CrossProcess.cs Updates to use new constructor
src/libraries/System.IO.Pipes/tests/PipeStreamConformanceTests.cs Updates to use new constructor

…lidate tests

Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com>
@Copilot Copilot AI requested a review from jozkee October 16, 2025 15:58
Copilot finished work on behalf of jozkee October 16, 2025 15:58
@jozkee jozkee requested a review from a team October 16, 2025 16:12
Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com>
Copilot finished work on behalf of jozkee October 16, 2025 16:22
@Copilot Copilot AI requested a review from jozkee October 16, 2025 16:22
Copy link
Member

@jeffhandley jeffhandley left a comment

Choose a reason for hiding this comment

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

Nice to see Copilot following our obsoletion instructions!

public NamedPipeClientStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: this(direction, isAsync, safePipeHandle)
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to file a breaking change for that? This can break any exist code I guess depending on isConnected?

Copy link
Member

@jozkee jozkee Oct 20, 2025

Choose a reason for hiding this comment

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

Only symptom is that on Connect[Async] we will stop throwing an unintended DirectoryNotFoundException and instead we will throw an InvalidOperationException because it will now be assumed that the pipe client is connected.

I would prefer not to file the breaking change because this behavior was not useful at all.

Copy link
Member

Choose a reason for hiding this comment

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

@copilot please add a test that creates a server and client named pipe, then re-creates the client named pipe from the existing client handle, then calls connect and assert that it throws InvalidOperationException. Test the new constructor, and the obsoleted constructor with both true/false for isConnected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Added test ConnectOnPipeFromExistingHandle_Throws_InvalidOperationException that validates the behavior for the new constructor and the obsolete constructor with both isConnected=true and isConnected=false. All three cases now throw InvalidOperationException when Connect is called, confirming that isConnected is ignored. Commit d5e8c89.

@tarekgh tarekgh added this to the 11.0.0 milestone Oct 20, 2025
…andle

Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com>
Copilot finished work on behalf of jozkee October 20, 2025 20:58
Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com>
Copilot finished work on behalf of jozkee October 21, 2025 16:36
@Copilot Copilot AI requested a review from jozkee October 21, 2025 16:36
Copy link
Member

@jozkee jozkee left a comment

Choose a reason for hiding this comment

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

@copilot, please address this feedback.

Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 21, 2025

@copilot, please address this feedback.

Done. Applied all feedback with commit 8f4a2d1:

  • Simplified test to pass SafePipeHandle directly instead of creating intermediate handles
  • Changed to use await Assert.ThrowsAsync pattern
  • Made test method async Task
  • Removed unnecessary comments
  • Added using for System.Threading.Tasks

@Copilot Copilot AI requested a review from jozkee October 21, 2025 17:15
Copilot finished work on behalf of jozkee October 21, 2025 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal]: Hide NamedPipeClientStream ctor with isConnected argument

5 participants