我的窗口上有两个Button
连接了两个ICommands
:
public ICommand Start { get; set; }
public ICommand Stop { get; set; }
像这样在
Constructor
中初始化的:Start = new Command(StartServer, (o) => !IsListening);
Stop = new Command(StopServer, (o) => IsListening);
并执行以下操作:
async void StartServer(object obj)
{
server.Start();
IsListening = true;
Status = "Listening";
try
{
while (IsListening)
{
var cw = new ClientWrapper();
cw.Client = await server.AcceptTcpClientAsync();
cw.EndPoint = cw.Client.Client.RemoteEndPoint;
Pool.Add(cw);
HandleClient(cw);
}
}
catch (Exception e)
{
throw;
}
}
void StopServer(object obj)
{
DisposeClients();
server.Stop();
IsListening = false;
Status = "Start Server";
}
当我单击
Start
时,它开始侦听并接受客户端,没有任何问题。没有任何客户端,如果我只是Start
服务器,然后单击Stop
,它将正常执行StopServer
函数,然后点击ICommand
的Execute
函数,并进入catch
方法的StartServer
块!并且e
中的消息是:无法访问已处置的对象。对象名称:
'System.Net.Sockets.Socket'。
我不希望它进入
catch
块!如何正确处理? 最佳答案
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace tcplistenertest
{
class Program
{
static void Main(string[] args)
{
Thread listenerThread = StartBackgroundThread(new ThreadStart(ThreadProc));
while(Console.ReadLine() != string.Empty)
{
}
mListener.Stop();
listenerThread.Join();
}
static void ThreadProc()
{
try
{
mListener = StartListening();
AcceptLoop(mListener);
}
catch(Exception e)
{
Console.WriteLine($"ThreadProc error: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
}
}
static Thread StartBackgroundThread(ThreadStart task)
{
Thread thread = new Thread(task);
thread.IsBackground = true;
thread.Start();
return thread;
}
static TcpListener StartListening()
{
TcpListener result = new TcpListener(IPAddress.Any, PORT);
result.Start();
return result;
}
static void AcceptLoop(TcpListener listener)
{
// this is the main loop of the Socket based server
while (true)
{
Socket socket = null;
try
{
Console.WriteLine("Accepting connection...");
socket = AcceptConnection(listener);
Console.WriteLine($"Connection accepted from {socket.RemoteEndPoint}");
}
catch (SocketException e)
{
Console.WriteLine($"Socket error accepting connection: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
break;
}
catch (Exception e)
{
Console.WriteLine($"Generic error accepting connection: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
break;
}
try
{
socket.Close();
}
catch (Exception e)
{
Console.WriteLine($"Error closing socket: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
break;
}
}
Console.WriteLine("Accept loop thread stopping");
}
static Socket AcceptConnection(TcpListener listener)
{
Socket socket = listener.AcceptSocket();
try
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, 1);
LingerOption optionValue = new LingerOption(true, 3);
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Linger, optionValue);
return socket;
}
catch (Exception)
{
socket.Close();
throw;
}
}
static TcpListener mListener;
const int PORT = 55000;
}
}
关于c# - 如何正确停止异步TcpListener?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58517207/