NamedPipeServerStream.EndWaitForConnection() 在使用时只是挂起

发布于 2025-01-02 16:50:07 字数 1499 浏览 3 评论 0原文

我第一次尝试使用命名管道。在此处的 MS 文档中,它指出:

每次调用 EndWaitForConnection 时都必须调用一次 开始等待连接。

因此,我试图成为一名优秀的小程序员并遵循文档,但是当我使用它时,EndWaitForConnection() 只是无限期地挂起。

因此,我将代码精简到最低限度,看看是否可以隔离问题,但不能解决问题。我从我编写的类中提取了以下代码。我对其进行了修改,使其开始等待管道连接,然后立即尝试停止等待该管道连接:

private void WaitForConnectionCallBack(IAsyncResult result)
{

}

public void Start()
{
    var tempPipe = new NamedPipeServerStream("TempPipe",
                                             PipeDirection.In,
                                             254, 
                                             PipeTransmissionMode.Message,
                                             PipeOptions.Asynchronous);

    IAsyncResult result = tempPipe.BeginWaitForConnection(
                                    new AsyncCallback(WaitForConnectionCallBack), this);

    tempPipe.EndWaitForConnection(result);  // <----- Hangs on this line right here
}

1) 为什么它挂在 EndWaitForConnection() 上?如果我想在收到连接之前关闭服务器,我该如何取消此 BeginWaitForConnection() 回调?

2)假设我没有上述问题。如果 2 个客户端尝试快速连接到我的命名管道,会发生什么情况?

我是否会收到每个连接的回调调用,或者是否必须等待接收第一个连接通知,然后快速调用 EndWaitForConnection(),然后再次调用 WaitForConnectionCallBack() 才能启动再次聆听下一个客户?

后者对我来说似乎是一个竞争条件,因为我可能无法足够快地设置连接侦听器。

I'm trying to use named pipes for the first time. In the MS documentation found here, it states that:

EndWaitForConnection must be called exactly once for every call to
BeginWaitForConnection.

So I'm trying to be a good little programmer and follow documentation, but the EndWaitForConnection() just hangs indefinitely when I use it.

So I stripped down my code to a bare minimum so see if I could isolate the problem but no dice. I've pulled the following code out of a class I've written. I've modified it so that it begins waiting on a pipe connection then immediately tries to stop waiting on that pipe connection:

private void WaitForConnectionCallBack(IAsyncResult result)
{

}

public void Start()
{
    var tempPipe = new NamedPipeServerStream("TempPipe",
                                             PipeDirection.In,
                                             254, 
                                             PipeTransmissionMode.Message,
                                             PipeOptions.Asynchronous);

    IAsyncResult result = tempPipe.BeginWaitForConnection(
                                    new AsyncCallback(WaitForConnectionCallBack), this);

    tempPipe.EndWaitForConnection(result);  // <----- Hangs on this line right here
}

1) Why does it hang on EndWaitForConnection()? If I want to shut down my server before I've received a connection, how can I essentially cancel this BeginWaitForConnection() callback?

2) Let's suppose that I did not have the above mentioned problem. What happens if 2 clients try to connect to my named pipe very quickly?

Do I get a callback invocation for each of them, or do I have to wait to receive the first connection notification then quickly call EndWaitForConnection() then WaitForConnectionCallBack() again to start listening for the next client again?

The latter seems like a race condition to me, because I may not set up the connection listener fast enough.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉薄对峙 2025-01-09 16:50:07

因此,对我有用的解决方案的基本框架如下:

private void WaitForConnectionCallBack(IAsyncResult result)
{
    try
    {
        PipeServer.EndWaitForConnection(result);

        /// ...
        /// Some arbitrary code
        /// ...
    }
    catch
    {
        // If the pipe is closed before a client ever connects,
        // EndWaitForConnection() will throw an exception.

        // If we are in here that is probably the case so just return.
        return;
    }
}

这是服务器代码。

public void Start()
{
    var server= new NamedPipeServerStream("TempPipe", 
                                          PipeDirection.In,
                                          254, 
                                          PipeTransmissionMode.Message, 
                                          PipeOptions.Asynchronous);

    // If nothing ever connects, the callback will never be called.
    server.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), this);

    // ... arbitrary code

// EndWaitForConnection() was not the right answer here, it would just wait indefinitely
// if you called it.  As Hans Passant mention, its meant to be used in the callback. 
// Which it now is. Instead, we are going to close the pipe.  This will trigger 
// the callback to get called.  

// However, the EndWaitForConnection() that will excecute in the callback will fail
// with an exception since the pipe is closed by time it gets invoked, 
// thus you must capture it with a try/catch

    server.Close(); // <--- effectively closes our pipe and gets our 
                        //       BeginWaitForConnection() moving, even though any future 
                        //       operations on the pipe will fail.
}

So, a basic skeleton of the solution that is working for me is as follows:

private void WaitForConnectionCallBack(IAsyncResult result)
{
    try
    {
        PipeServer.EndWaitForConnection(result);

        /// ...
        /// Some arbitrary code
        /// ...
    }
    catch
    {
        // If the pipe is closed before a client ever connects,
        // EndWaitForConnection() will throw an exception.

        // If we are in here that is probably the case so just return.
        return;
    }
}

Here is the Server code.

public void Start()
{
    var server= new NamedPipeServerStream("TempPipe", 
                                          PipeDirection.In,
                                          254, 
                                          PipeTransmissionMode.Message, 
                                          PipeOptions.Asynchronous);

    // If nothing ever connects, the callback will never be called.
    server.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), this);

    // ... arbitrary code

// EndWaitForConnection() was not the right answer here, it would just wait indefinitely
// if you called it.  As Hans Passant mention, its meant to be used in the callback. 
// Which it now is. Instead, we are going to close the pipe.  This will trigger 
// the callback to get called.  

// However, the EndWaitForConnection() that will excecute in the callback will fail
// with an exception since the pipe is closed by time it gets invoked, 
// thus you must capture it with a try/catch

    server.Close(); // <--- effectively closes our pipe and gets our 
                        //       BeginWaitForConnection() moving, even though any future 
                        //       operations on the pipe will fail.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文