diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs
index 0f58f95..13ae313 100644
--- a/test/netstd/Client/TestClient.cs
+++ b/test/netstd/Client/TestClient.cs
@@ -448,7 +448,7 @@
 
         public static byte[] PrepareTestData(bool randomDist, BinaryTestSize testcase)
         {
-            int amount = -1;
+            int amount;
             switch (testcase)
             {
                 case BinaryTestSize.Empty:
@@ -622,26 +622,29 @@
                 {
                     Console.WriteLine("*** FAILED ***");
                     returnCode |= ErrorContainers;
-                    throw new Exception("CrazyNesting.Equals failed");
                 }
             }
 
             // TODO: Validate received message
             Console.Write("testStruct({\"Zero\", 1, -3, -5})");
-            var o = new Xtruct();
-            o.String_thing = "Zero";
-            o.Byte_thing = (sbyte)1;
-            o.I32_thing = -3;
-            o.I64_thing = -5;
+            var o = new Xtruct
+            {
+                String_thing = "Zero",
+                Byte_thing = (sbyte)1,
+                I32_thing = -3,
+                I64_thing = -5
+            };
             var i = await client.testStructAsync(o, MakeTimeoutToken());
             Console.WriteLine(" = {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}");
 
             // TODO: Validate received message
             Console.Write("testNest({1, {\"Zero\", 1, -3, -5}, 5})");
-            var o2 = new Xtruct2();
-            o2.Byte_thing = (sbyte)1;
-            o2.Struct_thing = o;
-            o2.I32_thing = 5;
+            var o2 = new Xtruct2
+            {
+                Byte_thing = (sbyte)1,
+                Struct_thing = o,
+                I32_thing = 5
+            };
             var i2 = await client.testNestAsync(o2, MakeTimeoutToken());
             i = i2.Struct_thing;
             Console.WriteLine(" = {" + i2.Byte_thing + ", {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}, " + i2.I32_thing + "}");
@@ -838,16 +841,24 @@
             Console.WriteLine("}");
 
             // TODO: Validate received message
-            var insane = new Insanity();
-            insane.UserMap = new Dictionary<Numberz, long>();
-            insane.UserMap[Numberz.FIVE] = 5000L;
-            var truck = new Xtruct();
-            truck.String_thing = "Truck";
-            truck.Byte_thing = (sbyte)8;
-            truck.I32_thing = 8;
-            truck.I64_thing = 8;
-            insane.Xtructs = new List<Xtruct>();
-            insane.Xtructs.Add(truck);
+            var insane = new Insanity
+            {
+                UserMap = new Dictionary<Numberz, long>
+                {
+                    [Numberz.FIVE] = 5000L
+                }
+            };
+            var truck = new Xtruct
+            {
+                String_thing = "Truck",
+                Byte_thing = (sbyte)8,
+                I32_thing = 8,
+                I64_thing = 8
+            };
+            insane.Xtructs = new List<Xtruct>
+            {
+                truck
+            };
             Console.Write("testInsanity()");
             var whoa = await client.testInsanityAsync(insane, MakeTimeoutToken());
             Console.Write(" = {");
@@ -902,8 +913,10 @@
             sbyte arg0 = 1;
             var arg1 = 2;
             var arg2 = long.MaxValue;
-            var multiDict = new Dictionary<short, string>();
-            multiDict[1] = "one";
+            var multiDict = new Dictionary<short, string>
+            {
+                [1] = "one"
+            };
 
             var tmpMultiDict = new List<string>();
             foreach (var pair in multiDict)
diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs
index 25c2afc..280f4e9 100644
--- a/test/netstd/Server/TestServer.cs
+++ b/test/netstd/Server/TestServer.cs
@@ -181,19 +181,19 @@
 
         public class TestHandlerAsync : ThriftTest.IAsync
         {
-            public TServer server { get; set; }
-            private int handlerID;
-            private StringBuilder sb = new StringBuilder();
-            private TestLogDelegate logger;
+            public TServer Server { get; set; }
+            private readonly int handlerID;
+            private readonly StringBuilder sb = new StringBuilder();
+            private readonly TestLogDelegate logger;
 
             public TestHandlerAsync()
             {
                 handlerID = Interlocked.Increment(ref _clientID);
-                logger += testConsoleLogger;
+                logger += TestConsoleLogger;
                 logger.Invoke("New TestHandler instance created");
             }
 
-            public void testConsoleLogger(string msg, params object[] values)
+            public void TestConsoleLogger(string msg, params object[] values)
             {
                 sb.Clear();
                 sb.AppendFormat("handler{0:D3}:", handlerID);
@@ -525,117 +525,121 @@
 
         public static int Execute(List<string> args)
         {
-            var loggerFactory = new LoggerFactory();//.AddConsole().AddDebug();
-            var logger = new LoggerFactory().CreateLogger("Test");
-
-            try
+            using (var loggerFactory = new LoggerFactory()) //.AddConsole().AddDebug();
             {
-                var param = new ServerParam();
+                var logger = loggerFactory.CreateLogger("Test");
 
                 try
                 {
-                    param.Parse(args);
+                    var param = new ServerParam();
+
+                    try
+                    {
+                        param.Parse(args);
+                    }
+                    catch (Exception ex)
+                    {
+                        Console.WriteLine("*** FAILED ***");
+                        Console.WriteLine("Error while  parsing arguments");
+                        Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+                        return 1;
+                    }
+
+
+                    // Endpoint transport (mandatory)
+                    TServerTransport trans;
+                    switch (param.transport)
+                    {
+                        case TransportChoice.NamedPipe:
+                            Debug.Assert(param.pipe != null);
+                            trans = new TNamedPipeServerTransport(param.pipe);
+                            break;
+
+
+                        case TransportChoice.TlsSocket:
+                            var cert = GetServerCert();
+                            if (cert == null || !cert.HasPrivateKey)
+                            {
+                                cert?.Dispose();
+                                throw new InvalidOperationException("Certificate doesn't contain private key");
+                            }
+
+                        trans = new TTlsServerSocketTransport( param.port, cert,
+                                (sender, certificate, chain, errors) => true,
+                                null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12);
+                            break;
+
+                        case TransportChoice.Socket:
+                        default:
+                        trans = new TServerSocketTransport(param.port, 0);
+                            break;
+                    }
+
+                    // Layered transport (mandatory)
+                    TTransportFactory transFactory = null;
+                    switch (param.buffering)
+                    {
+                        case BufferChoice.Framed:
+                            transFactory = new TFramedTransport.Factory();
+                            break;
+                        case BufferChoice.Buffered:
+                            transFactory = new TBufferedTransport.Factory();
+                            break;
+                        default:
+                            Debug.Assert(param.buffering == BufferChoice.None, "unhandled case");
+                            transFactory = null;  // no layered transprt
+                            break;
+                    }
+
+                    // Protocol (mandatory)
+                    TProtocolFactory proto;
+                    switch (param.protocol)
+                    {
+                        case ProtocolChoice.Compact:
+                            proto = new TCompactProtocol.Factory();
+                            break;
+                        case ProtocolChoice.Json:
+                            proto = new TJsonProtocol.Factory();
+                            break;
+                        case ProtocolChoice.Binary:
+                        default:
+                            proto = new TBinaryProtocol.Factory();
+                            break;
+                    }
+
+                    // Processor
+                    var testHandler = new TestHandlerAsync();
+                    var testProcessor = new ThriftTest.AsyncProcessor(testHandler);
+                    var processorFactory = new TSingletonProcessorFactory(testProcessor);
+
+                    TServer serverEngine = new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger);
+
+                    //Server event handler
+                    var serverEvents = new MyServerEventHandler();
+                    serverEngine.SetEventHandler(serverEvents);
+
+                    // Run it
+                    var where = (!string.IsNullOrEmpty(param.pipe)) ? "on pipe " + param.pipe : "on port " + param.port;
+                    Console.WriteLine("Starting the AsyncBaseServer " + where +
+                                      " with processor TPrototypeProcessorFactory prototype factory " +
+                                      (param.buffering == BufferChoice.Buffered ? " with buffered transport" : "") +
+                                      (param.buffering == BufferChoice.Framed ? " with framed transport" : "") +
+                                      (param.transport == TransportChoice.TlsSocket ? " with encryption" : "") +
+                                      (param.protocol == ProtocolChoice.Compact ? " with compact protocol" : "") +
+                                      (param.protocol == ProtocolChoice.Json ? " with json protocol" : "") +
+                                      "...");
+                    serverEngine.ServeAsync(CancellationToken.None).GetAwaiter().GetResult();
+                    Console.ReadLine();
                 }
-                catch (Exception ex)
+                catch (Exception x)
                 {
-                    Console.WriteLine("*** FAILED ***");
-                    Console.WriteLine("Error while  parsing arguments");
-                    Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+                    Console.Error.Write(x);
                     return 1;
                 }
 
-
-                // Endpoint transport (mandatory)
-                TServerTransport trans;
-                switch (param.transport)
-                {
-                    case TransportChoice.NamedPipe:
-                        Debug.Assert(param.pipe != null);
-                        trans = new TNamedPipeServerTransport(param.pipe);
-                        break;
-
-
-                    case TransportChoice.TlsSocket:
-                        var cert = GetServerCert();
-                        if (cert == null || !cert.HasPrivateKey)
-                        {
-                            throw new InvalidOperationException("Certificate doesn't contain private key");
-                        }
-
-                        trans = new TTlsServerSocketTransport( param.port, cert,
-                            (sender, certificate, chain, errors) => true, 
-                            null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12);
-                        break;
-
-                    case TransportChoice.Socket:
-                    default:  
-                        trans = new TServerSocketTransport(param.port, 0);
-                        break;
-                }
-
-                // Layered transport (mandatory)
-                TTransportFactory transFactory = null;
-                switch (param.buffering)
-                {
-                    case BufferChoice.Framed:
-                        transFactory = new TFramedTransport.Factory();
-                        break;
-                    case BufferChoice.Buffered:
-                        transFactory = new TBufferedTransport.Factory();
-                        break;
-                    default:
-                        Debug.Assert(param.buffering == BufferChoice.None, "unhandled case");
-                        transFactory = null;  // no layered transprt
-                        break;
-                }
-
-                // Protocol (mandatory)
-                TProtocolFactory proto;
-                switch (param.protocol)
-                {
-                    case ProtocolChoice.Compact:
-                        proto = new TCompactProtocol.Factory();
-                        break;
-                    case ProtocolChoice.Json:
-                        proto = new TJsonProtocol.Factory();
-                        break;
-                    case ProtocolChoice.Binary:
-                    default:
-                        proto = new TBinaryProtocol.Factory();
-                        break;
-                }
-
-                // Processor
-                var testHandler = new TestHandlerAsync();
-                var testProcessor = new ThriftTest.AsyncProcessor(testHandler);
-                var processorFactory = new TSingletonProcessorFactory(testProcessor);
-
-                TServer serverEngine = new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger);
-
-                //Server event handler
-                var serverEvents = new MyServerEventHandler();
-                serverEngine.SetEventHandler(serverEvents);
-
-                // Run it
-                var where = (! string.IsNullOrEmpty(param.pipe)) ? "on pipe " + param.pipe : "on port " + param.port;
-                Console.WriteLine("Starting the AsyncBaseServer " + where +
-                                  " with processor TPrototypeProcessorFactory prototype factory " +
-                                  (param.buffering == BufferChoice.Buffered ? " with buffered transport" : "") +
-                                  (param.buffering == BufferChoice.Framed ? " with framed transport" : "") +
-                                  (param.transport == TransportChoice.TlsSocket ? " with encryption" : "") +
-                                  (param.protocol == ProtocolChoice.Compact ? " with compact protocol" : "") +
-                                  (param.protocol == ProtocolChoice.Json ? " with json protocol" : "") +
-                                  "...");
-                serverEngine.ServeAsync(CancellationToken.None).GetAwaiter().GetResult();
-                Console.ReadLine();
+                Console.WriteLine("done.");
+                return 0;
             }
-            catch (Exception x)
-            {
-                Console.Error.Write(x);
-                return 1;
-            }
-            Console.WriteLine("done.");
-            return 0;
         }
     }
 
