Отмена блокировки вызова AcceptTcpClient
Как все, возможно, уже знают, самый простой способ принять входящие TCP-соединения в C # - это циклическое выполнение по 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 () (который я закомментировал, потому что метод нет существует)