我正在构建一个使用IPC命名管道的应用程序。 当开始编写压力测试时,我发现了一个与客户端何时快速连接断开相关的问题。
服务器代码:
static void ServerThread()
{
var serverPipe = new NamedPipeServerStream("myipc", PipeDirection.InOut, -1, PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
serverPipe.BeginWaitForConnection(
ar =>
{
var thisPipe = (NamedPipeServerStream)ar.AsyncState;
thisPipe.EndWaitForConnection(ar);
Task.Factory.StartNew(ServerThread);
thisPipe.Dispose();
},
serverPipe);
}
客户端除了connect-disconnect之外什么都不做,如下所示:
static void RunClients()
{
for (int i = 0; i < 100; i++)
{
var clientPipe = new NamedPipeClientStream(".", "myipc", PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
clientPipe.Connect(1000);
clientPipe.Dispose();
}
}
当它运行时,其中一个客户端在Connect()中失败,而服务器在BeginWaitForConnection中失败 - 说管道正在关闭。 如果我在每个客户端处理之前至少添加Thread.Sleep(100) - 一切正常。 我确定我正在做的是一个角落案例,但我相信管道应该能够以富有成效的方式处理这个问题。
关于什么可能出错的任何想法?
谢谢!
答案 0 :(得分:2)
其中一个客户端在Connect()
中失败
因为服务器在连接后立即处理管道。
服务器在BeginWaitForConnection中失败
因为客户端在连接后立即处理管道。
我相信管道应该能够以慷慨的方式处理它。
确实如此,它优雅地抛出一个异常,让你的代码知道发生了异常。您似乎认为代码关闭管道而不做任何事情让另一端知道管道即将消失是正常的。这不正常,这是例外。所以你得到一个特殊的通知。
您可以使用try / catch捕获异常。您可以在catch处理程序中执行两项操作。您可以假设代码可以毫不费力地关闭管道,在这种情况下,除了关闭管道末端并离开外,您什么都不做。或者你可以假设发生了一些真正的坏事,因为管道的另一端并没有很好地说再见。这对于区分糟糕的事件非常重要,比如管道客户端或服务器崩溃。您可以选择自己喜欢的方式,但我强烈建议您不要忽视这种糟糕的情况,它确实会发生。你刚刚创造了一个很好的模拟这种事故。