当客户端只快速连接-断开连接时,命名管道将失败

本文关键字:连接 管道 失败 断开 客户端 | 更新日期: 2023-09-27 18:31:23

我正在构建一个使用 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);
}

客户端只执行以下连接-断开连接操作:

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) - 一切正常。我确定我正在做的是一个极端情况,但我相信管道应该能够以格雷斯的方式处理这个问题。

关于可能出错的任何想法?

谢谢!

当客户端只快速连接-断开连接时,命名管道将失败

其中一个客户端在 Connect() 中失败

因为服务器在连接后立即处理管道。

服务器在开始等待连接中失败

因为客户端在连接后立即处理管道。

我相信管道应该能够以格雷厄的方式处理这个问题。

确实如此,它会优雅地抛出异常,让您的代码知道发生了异常情况。 您似乎认为代码关闭管道而不执行任何操作以使另一端知道管道即将消失是正常的。 这是不正常的,这是例外。 因此,您会收到一个特殊的通知。

您可以使用 try/catch 捕获异常。 您可以在捕获处理程序中执行两件事。 您可以假设代码可以随意关闭管道,在这种情况下,除了关闭管道末端并退出之外,您什么都不做。 或者你可以假设发生了一些非常糟糕的事情,因为管道的另一端没有很好地说再见。 这对于区分哦废话类型的事故非常重要,例如管道客户端或服务器崩溃。 由您选择自己喜欢的方式,但我强烈建议不要忽略哦废话的情况,它确实会发生并且将会发生。 您刚刚创建了此类事故的良好模拟。