【发布时间】:2019-10-23 17:01:56
【问题描述】:
我的窗口上有两个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 块!如何正确处理?
【问题讨论】:
-
"我不希望它转到
catch块!" -catch块在服务器级别 没有任何影响;坦率地说,按照设计,套接字是凌乱而脆弱的:异常处理是正常的,也是意料之中的。 “如何妥善处理?” - 通过不在catch中调用throw:) -
@MarcGravell,由于
StopServer正常执行,我的TcpListener肯定没有问题。所以从这个await server.AcceptTcpClientAsync()行抛出异常!现在,如何在停止之前从AcceptTcpClientAsync停止服务器。如果无法限制AcceptTcpClientAsync,如果您不介意,请在答案部分提供一个小示例。 -
似乎没有接受 CancellationToken 的重载。因此,最好的办法是听从 Marc 的建议,在
await server.AcceptTcpClientAsync()周围使用 try/catch。无论如何我都会推荐。根据错误代码,您可以决定是否可以实际处理错误或退出循环。 -
@Fildor,几年前我尝试 beginaccept/endaccept 类型的异步操作时,我想我在那里使用了 socketerror。这些 async/await 有什么选择吗?
-
当然。 SocketException 具有 SocketErrorCode 属性。
标签: c# tcplistener