static void SendData(int order, string serverName, int portNumber, int numberOfEventsPerThread)
        {
            IntPtr        connectedEvent = InteropEvents.CreateEvent(IntPtr.Zero, true, false, string.Format("thread{0}connected", order));
            TcpConnection connection     = new TcpConnection(serverName, portNumber);

            connection.Connect();
            InteropEvents.SetEvent(connectedEvent);

            IntPtr startEvent = InteropEvents.OpenEvent(InteropEvents.EVENT_ALL_ACCESS | InteropEvents.EVENT_MODIFY_STATE, true, "startevent");
            uint   waitResult = InteropEvents.WaitForSingleObject(startEvent, -1);

            // Generate data and send it down the road

            var      r    = new Random();
            DateTime time = new DateTime(1971 + order * 10, 9, 12);

            for (int i = 0; i < numberOfEventsPerThread; i++)
            {
                var line = new StringBuilder();
                for (int j = 0; j < 60; j++)
                {
                    line.AppendFormat("field{0}={0}, ", j, r.Next(1000000));
                }
                line.Length -= 2;
                connection.Send(string.Format("{0} {1}\n", time, line));
                time = time.AddSeconds(1);
            }

            connection.Close();
            //Console.WriteLine("{0} Thread {1} is done with sending data", DateTime.Now, order);
        }
        static void Main(string[] args)
        {
            if (args.Length < 4)
            {
                ShowUsage();
                return;
            }

            // Parse the arguments
            string serverName              = args[0];
            int    portNumber              = Convert.ToInt32(args[1]);
            int    numberOfThreads         = Convert.ToInt32(args[2]);
            int    numberOfEventsPerThread = Convert.ToInt32(args[3]);
            IntPtr startEvent              = InteropEvents.CreateEvent(IntPtr.Zero, true, false, "startevent");

            // Launch X concurrent threads
            Thread[] threads = new Thread[numberOfThreads];
            for (int i = 0; i < numberOfThreads; i++)
            {
                int         order = i;
                ThreadStart start = delegate { SendData(order, serverName, portNumber, numberOfEventsPerThread); };
                Thread      t     = new Thread(start);
                t.Name = string.Format("Thread {0}", i);
                t.Start();
                threads[i] = t;
            }

            Console.WriteLine("{0} Started all threads", DateTime.Now);
            Thread.Sleep(5000);
            Console.WriteLine("{0} Waiting for all threads to get connected", DateTime.Now);
            // Wait for all threads to connect
            for (int i = 0; i < numberOfThreads; i++)
            {
                IntPtr handle     = InteropEvents.OpenEvent(InteropEvents.EVENT_ALL_ACCESS | InteropEvents.EVENT_MODIFY_STATE, true, string.Format("thread{0}connected", i));
                uint   waitResult = InteropEvents.WaitForSingleObject(handle, -1);
            }
            Console.WriteLine("{0} All threads connected", DateTime.Now);
            InteropEvents.SetEvent(startEvent);
            Console.WriteLine("{0} Fired starting event", DateTime.Now);

            DateTime tStart = DateTime.Now;

            for (int i = 0; i < numberOfThreads; i++)
            {
                threads[i].Join();
            }
            DateTime tEnd = DateTime.Now;

            Console.WriteLine("It took {0:F2} seconds to send {1} events", (tEnd - tStart).TotalSeconds, numberOfThreads * numberOfEventsPerThread);
        }