Istnieje serwer klasy TcpListener. Przyjmuje połączenia przychodzące za pomocą metody BeginAcceptTcpClient (AsyncCallback, Object).Metoda asynchroniczna uruchamia AsyncCallback w bieżącym wątku (wątek główny)
Kod jest napisany w przykładzie MSDN
public static ManualResetEvent tcpClientConnected =
new ManualResetEvent(false);
public static void DoBeginAcceptTcpClient(TcpListener
listener)
{
while(true)
{
tcpClientConnected.Reset();
Console.WriteLine("Waiting for a connection...");
listener.BeginAcceptTcpClient(
new AsyncCallback(DoAcceptTcpClientCallback),
listener);
tcpClientConnected.WaitOne();
}
}
public static void DoAcceptTcpClientCallback(IAsyncResult ar)
{
TcpListener listener = (TcpListener) ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
Console.WriteLine("Client connected completed");
tcpClientConnected.Set();
while(true)
{
//Receiving messages from the client
}
}
Problemem jest to, że DoAcceptTcpClientCallback (IAsyncResult ar) metoda czasami rozpoczyna wykonywanie w bieżącym wątku (główny), nie jest nowy, a bloki to (główne). Z tego powodu nie można uzyskać następujących połączeń. Proszę zrozumieć, dlaczego nie utworzyć wątku dla tej metody.
Nie pokazałeś nam, ale wyobrażam sobie, że '// Odbieranie wiadomości od klienta' z jakiegoś powodu wraca do korzystania z * synchronicznych * wywołań API. Nie rób tego. Gdy przejdziesz do asynchronizacji (w pewien sposób, który nie wymaga tworzenia wątków), nie wiesz, jakiego wątku będziesz używać - więc powinieneś uruchomić tylko tak długo, jak to konieczne, aby wysłać następną metodę asynchroniczną i następnie wróć. –
Po pierwsze, dlaczego nie używasz [AcceptTcpClientAsync] (https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.accepttcpclientasync%28v=vs.110%29.aspx?f = 255 & MSPPError = -2147217396)? Jest dostępny we wszystkich obsługiwanych wersjach .NET i znacznie ułatwia programowanie asynchroniczne. –
Drugi "asynchroniczny" nie oznacza "innego wątku". Oznacza to, że twój wątek nie będzie blokował czekania na odpowiedź. Operacje IO mogą nawet nie wymagać oddzielnego wątku, ponieważ IO w systemie Windows jest zawsze asynchroniczne na poziomie sterownika. API * emuluje * blokowanie, aby ułatwić programowanie jednowątkowe –