Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

HttpClient problems

This repo is made to demonstrate a problem I experience when using HttpClient in heavy load environments. The use of a for loop and multiple tasks spun up is a bit contrieved, but it is meant to simulate e.g. multiple integration tests running against the same service. We experience this problem when running multiple xUnit tests at once against a .NET Api, but the API itself is irrelevant, as the API side remains responsive the whole time while the client starts experiencing problems.

Unit tests

There is only one unit test file, but it is included in two projects, one .net core 2.0, and one desktop (.net 4.6.1), just to rule out that there are any important differences between the two. Running the tests reveal that .net core has is more efficient, as the parallel runs of the calls are much faster under load there than in the .net 4.6.1k one.

The Api

The API consists of two methods, api/values and api/values/slow. They both return an array of two strings, but the latter pauses for 200ms before responding. They are set up in VS to run on ports 58526 (http) and 44398 (https). I use both, to see if there are any differences between the two protocols, but there doesn't seem to be any.

The tests

The test run the two API calls a number of times each, over both http and https. Some tests run them in sequence, which is a lot slower, but always succeeds, and in parallel, starting N tasks, and Task.WhenAll-ing them at the end. There is only one HttpClient instance per endpoint (one for http, one for https).

Behavior

Running the tests, they start failing with TaskCancelledExceptions after a while when running multiple tests at the same time. How many simultaneous calls can go through, differ a bit between the fast and the slow API, and is probably hardware dependent, and varies a bit betwen runs. But it typically handles from 1,500 up to more than 10,000 simultaneous calls on the fast one, a bit fewer if I add custom headers, etc; and around 200 on the slow call (with 200ms artificial processing time on the server).

We see the same behaviour in our integration tests, but on much fewer connections. The calls there take much longer. If we run the tests again, separately, they always succeed. So the number of simultaneous calls are indeed important.

Goal

The goal of this repo is to get some firm answers on how to use multiple concurrent HttpClient connections at once from C# (be it from integration tests, or from server-side in e.g. a REST API, a windows service, etc)

  • What are the limits on the number of concurrent usages of a single HttpClient?
  • How is it related to the time used on each SendAsync call?
  • Other limits to know about?

About

Demonstrates a load problem using HttpClient in C#.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages