Last active
January 9, 2017 07:59
-
-
Save seif/ae2defbfa5afa26fa8f6 to your computer and use it in GitHub Desktop.
Mono WebRequest timeouts after ThreadPool exhaustion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Net; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Timers; | |
public class Test | |
{ | |
static int totalRequests = 0; | |
static bool threadPoolUsedUp; | |
public static void Main () | |
{ | |
ThreadPool.SetMinThreads (1, 1); | |
ThreadPool.SetMaxThreads (10, 10); | |
var timer = new System.Timers.Timer(500); | |
timer.Elapsed += MakeWebRequest; | |
timer.Start(); | |
UseUpThreadPool(); | |
Console.ReadLine(); | |
} | |
private static void MakeWebRequest(object source, ElapsedEventArgs e) | |
{ | |
var requestId = totalRequests++; | |
try | |
{ | |
var request = WebRequest.Create("http://www.google.com/"); | |
request.Timeout = 500; | |
using(var response = request.GetResponse()) | |
using(var reader = new StreamReader(response.GetResponseStream())) | |
{ | |
reader.ReadToEnd(); | |
Log(" Request #{0} succeeded.", requestId); | |
} | |
} | |
catch(Exception ex) | |
{ | |
int availableThreads, availableIoThreads; | |
ThreadPool.GetAvailableThreads(out availableThreads, out availableIoThreads); | |
Log(ex.Message + " Request #{0} Available Threads: {1} IO threads: {2}", requestId, availableThreads, availableIoThreads); | |
if(threadPoolUsedUp) | |
System.Environment.Exit(2); | |
} | |
if(threadPoolUsedUp) | |
System.Environment.Exit(0); | |
} | |
private static void UseUpThreadPool() | |
{ | |
Log(" Starting threads."); | |
var N = 100; | |
List<Task> tasks = new List<Task>(N); | |
for (int i = 0; i < N; i++) | |
{ | |
tasks.Add(Task.Factory.StartNew(() => Thread.Sleep(2000))); | |
} | |
Task.WaitAll(tasks.ToArray()); | |
int availableThreads, availableIoThreads; | |
ThreadPool.GetAvailableThreads(out availableThreads, out availableIoThreads); | |
Log(" Finished running tasks. Number of available threads: {0}", availableThreads); | |
threadPoolUsedUp = true; | |
} | |
private static void Log(string message, params object[] args) | |
{ | |
message = DateTime.Now.ToString() + message; | |
Console.WriteLine(message, args); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run locally: