context: //
  // Copyright (c) ZeroC, Inc. All rights reserved.
  //
  
  using Demo;
  using System;
  
  public class Client
  {
      public static int Main(string[] args)
      {
          int status = 0;
  
          try
          {
              //
              // The new communicator is automatically destroyed (disposed) at the end of the
              // using statement
              //
              using(var communicator = Ice.Util.initialize(ref args, "config.client"))
              {
                  //
                  // The communicator initialization removes all Ice-related arguments from args
                  //
                  if(args.Length > 0)
                  {
                      Console.Error.WriteLine("too many arguments");
                      status = 1;
                  }
                  else
                  {
                      status = run(communicator);
                  }
              }
          }
          catch(Exception ex)
          {
              Console.Error.WriteLine(ex);
              status = 1;
          }
  
          return status;
      }
  
      private static int run(Ice.Communicator communicator)
      {
          var throughput = ThroughputPrxHelper.checkedCast(communicator.propertyToProxy("Throughput.Proxy"));
          if(throughput == null)
          {
              Console.Error.WriteLine("invalid proxy");
              return 1;
          }
          var throughputOneway = ThroughputPrxHelper.uncheckedCast(throughput.ice_oneway());
  
          var byteSeq = new byte[ByteSeqSize.value];
  
          var stringSeq = new string[StringSeqSize.value];
          for(int i = 0; i < StringSeqSize.value; ++i)
          {
              stringSeq[i] = "hello";
          }
  
          var structSeq = new StringDouble[StringDoubleSeqSize.value];
          for(int i = 0; i < StringDoubleSeqSize.value; ++i)
          {
              structSeq[i] = new StringDouble();
              structSeq[i].s = "hello";
              structSeq[i].d = 3.14;
          }
  
          var fixedSeq = new Fixed[FixedSeqSize.value];
          for(int i = 0; i < FixedSeqSize.value; ++i)
          {
              fixedSeq[i].i = 0;
              fixedSeq[i].j = 0;
              fixedSeq[i].d = 0;
          }
  
          //
          // A method needs to be invoked thousands of times before the
          // JIT compiler will convert it to native code. To ensure an
          // accurate throughput measurement, we need to "warm up" the
          // JIT compiler.
          //
          {
              var warmupBytes = new byte[1];
              var warmupStrings = new string[1];
              var warmupStructs = new StringDouble[1];
              warmupStructs[0] = new StringDouble();
              var warmupFixed = new Fixed[1];
  
              throughput.startWarmup();
  
              Console.Error.Write("warming up the client/server...");
              Console.Error.Flush();
              for(int i = 0; i < 10000; i++)
              {
                  throughput.sendByteSeq(warmupBytes);
                  throughput.sendStringSeq(warmupStrings);
                  throughput.sendStructSeq(warmupStructs);
                  throughput.sendFixedSeq(warmupFixed);
  
                  throughput.recvByteSeq();
                  throughput.recvStringSeq();
                  throughput.recvStructSeq();
                  throughput.recvFixedSeq();
  
                  throughput.echoByteSeq(warmupBytes);
                  throughput.echoStringSeq(warmupStrings);
                  throughput.echoStructSeq(warmupStructs);
                  throughput.echoFixedSeq(warmupFixed);
              }
              throughput.endWarmup();
  
              Console.Error.WriteLine("ok");
          }
  
          menu();
  
          //
          // By default use byte sequence.
          //
          char currentType = '1';
          int seqSize = ByteSeqSize.value;
  
          string line = null;
          do
          {
              try
              {
                  Console.Write("==> ");
                  Console.Out.Flush();
                  line = Console.In.ReadLine();
                  if(line == null)
                  {
                      break;
                  }
  
                  long tmsec = DateTime.Now.Ticks / 10000;
                  int repetitions = 100;
  
                  if(line.Equals("1") || line.Equals("2") || line.Equals("3") || line.Equals("4"))
                  {
                      currentType = line[0];
                      switch(currentType)
                      {
                          case '1':
                          {
                              Console.WriteLine("using byte sequences");
                              seqSize = ByteSeqSize.value;
                              break;
                          }
                          case '2':
                          {
                              Console.WriteLine("using string sequences");
                              seqSize = StringSeqSize.value;
                              break;
                          }
                          case '3':
                          {
                              Console.WriteLine("using variable-length struct sequences");
                              seqSize = StringDoubleSeqSize.value;
                              break;
                          }
                          case '4':
                          {
                              Console.WriteLine("using fixed-length struct sequences");
                              seqSize = FixedSeqSize.value;
                              break;
                          }
                      }
                  }
                  else if(line.Equals("t") || line.Equals("o") || line.Equals("r") || line.Equals("e"))
                  {
                      if(currentType == '1')
                      {
                          repetitions = 1000; // Use more iterations for  byte sequences as it's a lot faster
                      }
  
                      char c = line[0];
                      switch (c)
                      {
                          case 't':
                          {
                              Console.Write("sending");
                              break;
                          }
                          case 'o':
                          {
                              Console.Write("sending");
                              break;
                          }
                          case 'r':
                          {
                              Console.Write("receiving");
                              break;
                          }
                          case 'e':
                          {
                              Console.Write("sending and receiving");
                              break;
                          }
                      }
  
                      Console.Write(" " + repetitions);
                      switch(currentType)
                      {
                          case '1':
                          {
                              Console.Write(" byte");
                              break;
                          }
                          case '2':
                          {
                              Console.Write(" string");
                              break;
                          }
                          case '3':
                          {
                              Console.Write(" variable-length struct");
                              break;
                          }
                          case '4':
                          {
                              Console.Write(" fixed-length struct");
                              break;
                          }
                      }
                      Console.Write(" sequences of size " + seqSize);
  
                      if(c == 'o')
                      {
                          Console.Write(" as oneway");
                      }
  
                      Console.WriteLine("...");
  
                      for (int i = 0; i < repetitions; ++i)
                      {
                          switch(currentType)
                          {
                              case '1':
                              {
                                  switch(c)
                                  {
                                      case 't':
                                      {
                                          throughput.sendByteSeq(byteSeq);
                                          break;
                                      }
  
                                      case 'o':
                                      {
                                          throughputOneway.sendByteSeq(byteSeq);
                                          break;
                                      }
  
                                      case 'r':
                                      {
                                          throughput.recvByteSeq();
                                          break;
                                      }
  
                                      case 'e':
                                      {
                                          throughput.echoByteSeq(byteSeq);
                                          break;
                                      }
                                  }
                                  break;
                              }
  
                              case '2':
                              {
                                  switch(c)
                                  {
                                      case 't':
                                      {
                                          throughput.sendStringSeq(stringSeq);
                                          break;
                                      }
  
                                      case 'o':
                                      {
                                          throughputOneway.sendStringSeq(stringSeq);
                                          break;
                                      }
  
                                      case 'r':
                                      {
                                          throughput.recvStringSeq();
                                          break;
                                      }
  
                                      case 'e':
                                      {
                                          throughput.echoStringSeq(stringSeq);
                                          break;
                                      }
                                  }
                                  break;
                              }
  
                              case '3':
                              {
                                  switch(c)
                                  {
                                      case 't':
                                      {
                                          throughput.sendStructSeq(structSeq);
                                          break;
                                      }
  
                                      case 'o':
                                      {
                                          throughputOneway.sendStructSeq(structSeq);
                                          break;
                                      }
  
                                      case 'r':
                                      {
                                          throughput.recvStructSeq();
                                          break;
                                      }
  
                                      case 'e':
                                      {
                                          throughput.echoStructSeq(structSeq);
                                          break;
                                      }
                                  }
                                  break;
                              }
  
                              case '4':
                              {
                                  switch(c)
                                  {
                                      case 't':
                                      {
                                          throughput.sendFixedSeq(fixedSeq);
                                          break;
                                      }
  
                                      case 'o':
                                      {
                                          throughputOneway.sendFixedSeq(fixedSeq);
                                          break;
                                      }
  
                                      case 'r':
                                      {
                                          throughput.recvFixedSeq();
                                          break;
                                      }
  
                                      case 'e':
                                      {
                                          throughput.echoFixedSeq(fixedSeq);
                                          break;
                                      }
                                  }
                                  break;
                              }
                          }
                      }
  
                      double dmsec = DateTime.Now.Ticks / 10000 - tmsec;
                      Console.WriteLine("time for " + repetitions + " sequences: " + dmsec.ToString("F") + "ms");
                      Console.WriteLine("time per sequence: " + ((double)(dmsec / repetitions)).ToString("F") + "ms");
                      int wireSize = 0;
                      switch(currentType)
                      {
                          case '1':
                          {
                              wireSize = 1;
                              break;
                          }
                          case '2':
                          {
  
gt:                             wireSize = stringSeq[0].Length;