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

"Managing Connections" mistakenly suggests that ServicePointManager is used globally #9295

Closed
1 of 3 tasks
erikness opened this issue Nov 29, 2018 · 6 comments · Fixed by #22492
Closed
1 of 3 tasks
Assignees
Labels
doc-bug Problem with the content; needs to be fixed [org][type][category] dotnet-framework/svc modern-web-apps-azure/subsvc networking/subsvc Pri1 High priority, do before Pri2 and Pri3

Comments

@erikness
Copy link

erikness commented Nov 29, 2018

Issue description

The "Managing Connections" doc describes how to use ServicePoint and ServicePointManager objects to manage TCP connections. These objects don't do anything themselves; they mostly hold configuration. The issue is that these are not used everywhere in .NET: some ways of sending network requests obey the restrictions you set in ServicePoint/ServicePointManager, but some other ways keep their configuration elsewhere.

Let me get specific.

The standard way of sending an HTTP request involves first creating an HttpClient object. You can optionally inject an HttpMessageListener object into HttpClient which controls much of HttpClient's behavior. If you don't specify one, HttpClient will use an instance of the class HttpClientHandler (which implements HttpMessageListener).

Microsoft provides an alternative handler called WinHttpHandler as well. There are some other handlers that I haven't explored I believe and developers are free to implement their own.

HttpClientHandler uses ServicePointManager to manage its TCP connections. But WinHttpHandler uses the windows library WinHTTP to manage its TCP connections. This means that if you change the properties of ServicePointManager or any specific ServicePoint object and then use WinHttpHandler to send HTTP requests, your changes won't have any affect.

For example, to set the maximum number of connections allowed per endpoint:

  • HttpClientHandler: set ServicePointManager.DefaultConnectionLimit (this will set the behavior for all HttpClientHandler instances)
  • WinHttphandler: set the MaxConnectionsPerServer property on the handler instance. The value is different for each handler.
  • SocketsHttphandler (in .NET Core only): set the MaxConnectionsPerServerproperty on the handler instance

The issue with this doc is that it speaks about ServicePointManager as though it manages TCP connections no matter what, when in fact it only manages TCP connections for some handler classes. I don't actually know the complete description of what's going on here. It should at least mention that if you're using WinHttpHandler or SocketsHttpHandler that you should not use ServicePointManager.

Reproduction

Here's a sketch of a repro (let me know if it doesn't work and I can get you a real version):

  • Make an HTTP client and give its constructor a HttpClientHandler object.
  • Send a bunch of requests to a single endpoint (i.e. example.com or localhost:8080).
  • While those requests are ongoing, find the ServicePoint for that endpoint with ServicePointManager.FindServicePoint(/* uri */)
  • Find the current number of active connections with servicePoint.CurrentConnections and print it to the screen. It should be greater than zero because you have requests in progress.
    • Note: by default, ServicePointManager caps this at 2 for remote websites
  • Now change the handler you give to HttpClient to WinHttpHandler instead. Now, CurrentConnections will be zero while you have requests in progress.

Related info

You might object that the doc is scoped correctly because WinHttpHandler is not included with .NET Framework by default (you have to get it from a NuGet package). My feeling from reading StackOverflow links is that WinHttpHandler is the most modern handler for .NET Framework projects; for example, it's the only one that supports HTTP/2. In addition, in .NET Core, HttpClientHandler uses WinHttpHandler behind the scenes.

In addition, .NET introduces a new handler called SocketsHttpHandler. I believe it manages its own connections so I'd bet it doesn't use ServicePoint's either.

Target framework

Check the .NET target framework(s) being used, and include the version number(s).

  • .NET Core
  • .NET Framework 4.7.2
  • .NET Standard
About VS info
Microsoft Visual Studio Enterprise 2017 
Version 15.9.2
VisualStudio.15.Release/15.9.2+28307.108
Microsoft .NET Framework
Version 4.7.03190

Installed Version: Enterprise

Architecture Diagrams and Analysis Tools   00369-60000-00001-AA363
Microsoft Architecture Diagrams and Analysis Tools

Visual C++ 2017   00369-60000-00001-AA363
Microsoft Visual C++ 2017

Application Insights Tools for Visual Studio Package   8.14.11009.1
Application Insights Tools for Visual Studio

ASP.NET and Web Tools 2017   15.9.04012.0
ASP.NET and Web Tools 2017

ASP.NET Core Razor Language Services   15.8.31590
Provides languages services for ASP.NET Core Razor.

ASP.NET Web Frameworks and Tools 2012   4.0.30625.0
For additional information, visit https://www.asp.net/

ASP.NET Web Frameworks and Tools 2017   5.2.60913.0
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0   15.9.03024.0
Azure App Service Tools v3.0.0

Azure Functions and Web Jobs Tools   15.9.02046.0
Azure Functions and Web Jobs Tools

C# Tools   2.10.0-beta2-63501-03+b9fb1610c87cccc8ceb74a770dba261a58e39c4a
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Cookiecutter   15.9.18254.1
Provides tools for finding, instantiating and customizing templates in cookiecutter format.

Extensibility Tools   1.10.211
Contains numerous tools and helpers that makes it easier than ever to build Visual Studio extensions.

JavaScript Language Service   2.0
JavaScript Language Service

JavaScript Project System   2.0
JavaScript Project System

JavaScript UWP Project System   2.0
JavaScript UWP Project System

Microsoft Azure Tools   2.9
Microsoft Azure Tools for Microsoft Visual Studio 2017 - v2.9.10730.2

Microsoft Continuous Delivery Tools for Visual Studio   0.4
Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft Library Manager   1.0
Install client-side libraries easily to any web project

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual C++ Wizards   1.0
Microsoft Visual C++ Wizards

Microsoft Visual Studio Tools for Containers   1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

Microsoft Visual Studio VC Package   1.0
Microsoft Visual Studio VC Package

MLGen Package Extension   1.0
MLGen Package Visual Studio Extension Detailed Info

NuGet Package Manager   4.6.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

ProjectServicesPackage Extension   1.0
ProjectServicesPackage Visual Studio Extension Detailed Info

Python   15.9.18254.1
Provides IntelliSense, projects, templates, debugging, interactive windows, and other support for Python developers.

Python - Django support   15.9.18254.1
Provides templates and integration for the Django web framework.

Python - IronPython support   15.9.18254.1
Provides templates and integration for IronPython-based projects.

Python - Profiling support   15.9.18254.1
Profiling support for Python projects.

ResourcePackage Extension   1.0
ResourcePackage Visual Studio Extension Detailed Info

ResourcePackage Extension   1.0
ResourcePackage Visual Studio Extension Detailed Info

Snapshot Debugging Extension   1.0
Snapshot Debugging Visual Studio Extension Detailed Info

SQL Server Data Tools   15.1.61810.11040
Microsoft SQL Server Data Tools

Test Adapter for Boost.Test   1.0
Enables Visual Studio's testing tools with unit tests written for Boost.Test.  The use terms and Third Party Notices are available in the extension installation directory.

Test Adapter for Google Test   1.0
Enables Visual Studio's testing tools with unit tests written for Google Test.  The use terms and Third Party Notices are available in the extension installation directory.

TypeScript Tools   15.9.20918.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   2.10.0-beta2-63501-03+b9fb1610c87cccc8ceb74a770dba261a58e39c4a
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools 10.2 for F# 4.5   15.8.0.0.  Commit Hash: 6e26c5bacc8c4201e962f5bdde0a177f82f88691.
Microsoft Visual F# Tools 10.2 for F# 4.5

Visual Studio Code Debug Adapter Host Package   1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Tools for CMake   1.0
Visual Studio Tools for CMake

Visual Studio Tools for Containers   1.0
Visual Studio Tools for Containers

Visual Studio Tools for Universal Windows Apps   15.0.28301.59
The Visual Studio Tools for Universal Windows apps allow you to build a single universal app experience that can reach every device running Windows 10: phone, tablet, PC, and more. It includes the Microsoft Windows 10 Software Development Kit.

Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

@erikness erikness changed the title "Managing Connections" does not describe "Managing Connections" mistakenly suggests that ServicePointManager is used globally Nov 29, 2018
@erikness
Copy link
Author

See this comment about the implementation: https://github.com/dotnet/corefx/issues/11224#issuecomment-289141149

Relevant portion:

While we have brought ServicePointManager and HttpWebRequest for platform parity, it doesn't support most of the functionality in .Net Core as the underlying stack resolves to either WinHTTP or Curl which do not expose the advanced control knobs.

Using ServicePointManager to control HttpClient is actually a side-effect on using HttpWebRequest and the managed HTTP stack on .Net Framework. Since WinHttpHandler/CurlHandler are used on .Net Core, SPM has no control over HttpClient instances.

@tdykstra
Copy link
Contributor

@karelz is there any more we should add to this doc besides

mention that if you're using WinHttpHandler or SocketsHttpHandler that you should not use ServicePointManager.

@tdykstra tdykstra added doc-bug Problem with the content; needs to be fixed [org][type][category] P2 waiting-on-feedback Waiting for feedback from SMEs before they can be merged labels Nov 21, 2019
@mairaw
Copy link
Contributor

mairaw commented Nov 22, 2019

Tagging @davidsh as well.

@davidsh
Copy link
Contributor

davidsh commented Feb 5, 2020

In general, on .NET Core, ServicePointManager is not used at all.

ServicePoint/ServicePointManager are considered legacy and are only stubbed out in .NET Core. Very little is used by any of the networking stack in .NET Core, in only a few places referenced from HttpWebRequest (also legacy) in an attempt to respect some globally-set settings. ServicePoint doesn’t track anything about current connections used by HttpClient (or HttpWebRequest, that layers on top of it) and is hardcoded to return 0:

https://github.com/dotnet/runtime/blob/099a5124458b6ce4a11e3c4f6159ec4c3bcd9700/src/libraries/System.Net.ServicePoint/src/System/Net/ServicePoint.cs#L93

@tdykstra tdykstra added P1 and removed P2 waiting-on-feedback Waiting for feedback from SMEs before they can be merged labels Feb 5, 2020
@andrewfinnell
Copy link

@erikness This comment saved me hours of time trying to figure out why my HttpClient wouldn't obey the ServicePointManager settings. It was because I used my own HttpClientHandler. I never would have know the default handler is what picks up the setting from the ServicePoint if not for your comment.

Thank you.

@dotnet-bot
Copy link
Contributor

This issue has been closed as part of the issue backlog grooming process outlined in #22351.

That automated process may have closed some issues that should be addressed. If you think this is one of them, reopen it with a comment explaining why. Tag the @dotnet/docs team for visibility.

@dotnet-bot dotnet-bot added the won't fix Issues that were closed as part of automated backlog grooming label Jan 25, 2021
@tdykstra tdykstra removed the won't fix Issues that were closed as part of automated backlog grooming label Jan 25, 2021
@tdykstra tdykstra reopened this Jan 25, 2021
@tdykstra tdykstra self-assigned this Jan 25, 2021
@gewarren gewarren added Pri1 High priority, do before Pri2 and Pri3 and removed P1 Pri2 labels Jan 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-bug Problem with the content; needs to be fixed [org][type][category] dotnet-framework/svc modern-web-apps-azure/subsvc networking/subsvc Pri1 High priority, do before Pri2 and Pri3
Projects
None yet
Development

Successfully merging a pull request may close this issue.