Как все уже знают, самый простой способ принять входящие TCP-соединения в С# - это перебрать TcpListener.AcceptTcpClient(). Кроме того, этот способ блокирует выполнение кода до получения соединения. Это чрезвычайно ограничивает GUI, поэтому я хочу слушать соединения в отдельном потоке или задаче.
Мне сказали, что потоки имеют несколько недостатков, однако никто не объяснил мне, что это такое. Поэтому вместо использования потоков я использовал задачи. Это отлично работает, но поскольку метод AcceptTcpClient блокирует выполнение, я не могу найти способ справиться с отменой задачи.
В настоящее время код выглядит так, но я понятия не имею, как я хочу отменить задачу, когда хочу, чтобы программа прекратила прослушивание соединений.
Сначала выполните функцию, выполняемую в задаче:
static void Listen () {
// Create listener object
TcpListener serverSocket = new TcpListener ( serverAddr, serverPort );
// Begin listening for connections
while ( true ) {
try {
serverSocket.Start ();
} catch ( SocketException ) {
MessageBox.Show ( "Another server is currently listening at port " + serverPort );
}
// Block and wait for incoming connection
if ( serverSocket.Pending() ) {
TcpClient serverClient = serverSocket.AcceptTcpClient ();
// Retrieve data from network stream
NetworkStream serverStream = serverClient.GetStream ();
serverStream.Read ( data, 0, data.Length );
string serverMsg = ascii.GetString ( data );
MessageBox.Show ( "Message recieved: " + serverMsg );
// Close stream and TcpClient connection
serverClient.Close ();
serverStream.Close ();
// Empty buffer
data = new Byte[256];
serverMsg = null;
}
}
Во-вторых, функции, запускающие и останавливающие прослушивание:
private void btnListen_Click (object sender, EventArgs e) {
btnListen.Enabled = false;
btnStop.Enabled = true;
Task listenTask = new Task ( Listen );
listenTask.Start();
}
private void btnStop_Click ( object sender, EventArgs e ) {
btnListen.Enabled = true;
btnStop.Enabled = false;
//listenTask.Abort();
}
Мне просто нужно что-то заменить для вызова listenTask.Abort() (который я прокомментировал, потому что метод не существует)