誰もが知っているように、C# で着信 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() 呼び出しを置き換える何かが必要なだけです(メソッドが存在しないため、コメントアウトしました)