소스 검색

[HttpWebRequest] Avoid using the threadpool for synchronous requests

The code path for synchronous requests was the same as the one for
asynchronous ones: the threadpool. It's actually not needed in this
case because the thread is going to wait anyway, so there's no need
to use the threadpool.

This helps in scenarios in which SOA is heavily used:
- The process is hosted under xsp/mono-fastcgi/... which use the threadpool
too.
- If the requests generate other requests to other REST services, the
usage of the threadpool in these cases may interfere with the usage of
the threadpool by xsp/mono-fastcgi/...
- The thread that is serving a request shouldn't request another thread
for a blocking operation, preventing the use of that thread by other
possible incoming requests.

This commit is contributed under the terms of MIT/X11 licence.

(It doesn't cause any breakage in the System test suite.)
Andres G. Aragoneses 13 년 전
부모
커밋
b190db44cb
2개의 변경된 파일12개의 추가작업 그리고 3개의 파일을 삭제
  1. 3 0
      mcs/class/System/System.Net/HttpWebRequest.cs
  2. 9 3
      mcs/class/System/System.Net/WebConnection.cs

+ 3 - 0
mcs/class/System/System.Net/HttpWebRequest.cs

@@ -929,9 +929,12 @@ namespace System.Net
 
 		public override WebResponse GetResponse()
 		{
+			asynchronous = false;
 			WebAsyncResult result = (WebAsyncResult) BeginGetResponse (null, null);
 			return EndGetResponse (result);
 		}
+
+		internal bool asynchronous = true;
 		
 		internal bool FinishedReading {
 			get { return finished_reading; }

+ 9 - 3
mcs/class/System/System.Net/WebConnection.cs

@@ -58,6 +58,7 @@ namespace System.Net
 		object socketLock = new object ();
 		WebExceptionStatus status;
 		WaitCallback initConn;
+		Action<object> initConnDelegate;
 		bool keepAlive;
 		byte [] buffer;
 		static AsyncCallback readDoneDelegate = new AsyncCallback (ReadDone);
@@ -109,11 +110,12 @@ namespace System.Net
 			this.sPoint = sPoint;
 			buffer = new byte [4096];
 			Data = new WebConnectionData ();
-			initConn = new WaitCallback (state => {
+			initConnDelegate = state => {
 				try {
 					InitConnection (state);
 				} catch {}
-				});
+			};
+			initConn = new WaitCallback (state => initConnDelegate (state));
 			queue = group.Queue;
 			abortHelper = new AbortHelper ();
 			abortHelper.Connection = this;
@@ -787,7 +789,11 @@ namespace System.Net
 				if (!busy) {
 					busy = true;
 					status = WebExceptionStatus.Success;
-					ThreadPool.QueueUserWorkItem (initConn, request);
+
+					if (request.asynchronous)
+						ThreadPool.QueueUserWorkItem (initConn, request);
+					else
+						initConnDelegate (request);
 				} else {
 					lock (queue) {
 #if MONOTOUCH