public void RegisterClientHandler(ClientHandler ch) { ch_ = ch; }
public void Start(int backlog = 20) { if (!isListening.get()) { isListening.set(true); //listenTask = Task.Run(() => listenThread = new Thread(() => { int client_count = 0; listenSocket_.Listen(backlog); List <Thread> serviceQ_ = new List <Thread>(); while (isListening.get() && (client_count++ < NumClients || NumClients == -1)) { Socket client_socket = listenSocket_.Accept(); if (client_socket != null) { if (ch_ != null) { ClientHandler ch = ch_.Clone(); ch.SetSocket(client_socket); ch.SetServiceEndPoint(listen_ep_); // same principle effect as Dr. Fawcett's C++ ThreadPool // (see the C++ version, TCPResponder.cpp) // each client is service on a separate thread pool task (a C# future) //here we use the blocking queue to signal when to exit; /* service_queue.enQ(Task.Run(() => * { * ServiceClient(ch); * return true; * })); */ // wait for all service threads to complete Thread serviceClient = new Thread(() => ServiceClient(ch)); serviceQ_.Add(serviceClient); serviceClient.Start(); } } } // wait for all service tasks to complete for (int i = 0; i < serviceQ_.Count; ++i) { serviceQ_[i].Join(); } // use to null to signal complete /* service_queue.enQ(Task.Run(() => false)); * Task<bool> client_task; * * // wait for all service threads to complete * do * { * client_task = service_queue.deQ(); * client_task.Wait(); * } * while (client_task.Result == true); */ }); listenThread.Start(); } }