THRIFT-25. csharp: Various compiler and library improvements

Compiler:
- Thrift structures are serializable.
- The member fields of thrift structures are now private and only accessible
  through Properties, which keep the appropriate __isset up to date.

Library
- Addition of TBufferedTransport, which can be used to wrap other Transports.
- Addition of TThreadedServer, which manually manages threads instead of
  relying on .NET ThreadPool.
- Servers use a log delegate that defaults to System.Console but allows
  servers to use log4net without introducing the dependency.

ThriftTest Visual Studio Project
- Test client and server that use ThriftTest.thrift. The project references
  thrift.exe and Thrift.dll from the subversion tree and automatically builds
  generated code. This makes it very easy to test changes in both the compiler
  and library.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@732079 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/csharp/src/Server/TThreadPoolServer.cs b/lib/csharp/src/Server/TThreadPoolServer.cs
index ac7aa8b..b44487f 100644
--- a/lib/csharp/src/Server/TThreadPoolServer.cs
+++ b/lib/csharp/src/Server/TThreadPoolServer.cs
@@ -31,10 +31,19 @@
 			:this(processor, serverTransport,
 				 new TTransportFactory(), new TTransportFactory(),
 				 new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
-				 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS)
+				 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate)
 		{
 		}
 
+		public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
+			: this(processor, serverTransport,
+				 new TTransportFactory(), new TTransportFactory(),
+				 new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+				 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, logDelegate)
+		{
+		}
+
+
 		public TThreadPoolServer(TProcessor processor,
 								 TServerTransport serverTransport,
 								 TTransportFactory transportFactory,
@@ -42,7 +51,7 @@
 			:this(processor, serverTransport,
 				 transportFactory, transportFactory,
 				 protocolFactory, protocolFactory,
-				 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS)
+				 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate)
 		{
 		}
 
@@ -52,9 +61,9 @@
 								 TTransportFactory outputTransportFactory,
 								 TProtocolFactory inputProtocolFactory,
 								 TProtocolFactory outputProtocolFactory,
-								 int minThreadPoolThreads, int maxThreadPoolThreads)
+								 int minThreadPoolThreads, int maxThreadPoolThreads, LogDelegate logDel)
 			:base(processor, serverTransport, inputTransportFactory, outputTransportFactory,
-				  inputProtocolFactory, outputProtocolFactory)
+				  inputProtocolFactory, outputProtocolFactory, logDel)
 		{
 			if (!ThreadPool.SetMinThreads(minThreadPoolThreads, minThreadPoolThreads))
 			{
@@ -64,7 +73,6 @@
 			{
 				throw new Exception("Error: could not SetMaxThreads in ThreadPool");
 			}
-
 		}
 
 		/// <summary>
@@ -78,7 +86,7 @@
 			}
 			catch (TTransportException ttx)
 			{
-				Console.Error.WriteLine("Error, could not listen on ServerTransport: " + ttx);
+				logDelegate("Error, could not listen on ServerTransport: " + ttx);
 				return;
 			}
 
@@ -92,8 +100,16 @@
 				}
 				catch (TTransportException ttx)
 				{
-					++failureCount;
-					Console.Error.WriteLine(ttx);
+					if (stop)
+					{
+						logDelegate("TThreadPoolServer was shutting down, caught " + ttx.GetType().Name);
+					}
+					else
+					{
+						++failureCount;
+						logDelegate(ttx.ToString());
+					}
+
 				}
 			}
 
@@ -105,18 +121,12 @@
 				}
 				catch (TTransportException ttx)
 				{
-					Console.Error.WriteLine("TServerTrasnport failed on close: " + ttx.Message);
+					logDelegate("TServerTransport failed on close: " + ttx.Message);
 				}
 				stop = false;
 			}
 		}
 
-
-		public override void Stop()
-		{
-			stop = true;
-		}
-
 		/// <summary>
 		/// Loops on processing a client forever
 		/// threadContext will be a TTransport instance
@@ -143,11 +153,12 @@
 			catch (TTransportException)
 			{
 				// Assume the client died and continue silently
+				//Console.WriteLine(ttx);
 			}
 			
 			catch (Exception x)
 			{
-				Console.Error.WriteLine("Error: " + x);
+				logDelegate("Error: " + x);
 			}
 
 			if (inputTransport != null)
@@ -159,5 +170,11 @@
 				outputTransport.Close();
 			}
 		}
+
+		public override void Stop()
+		{
+			stop = true;
+			serverTransport.Close();
+		}
 	}
 }