NamedPipeServerStream.EndWaitForConnection()在使用时仅挂起
本文关键字:挂起 EndWaitForConnection NamedPipeServerStream | 更新日期: 2023-09-27 18:22:25
我第一次尝试使用命名管道。在这里找到的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) 假设我没有上述问题。如果两个客户端尝试快速连接到我的命名管道,会发生什么?
我是为它们中的每一个都得到回调调用,还是必须等待接收第一个连接通知,然后快速调用EndWaitForConnection()
,然后再次调用WaitForConnectionCallBack()
,才能再次开始侦听下一个客户端?
后者对我来说似乎是一个竞争条件,因为我可能没有足够快地设置连接侦听器。
因此,适用于我的解决方案的基本框架如下:
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.
}