[英]NamedPipeClientStream.Connect() throws System.IO.FileNotFoundException: Unable to find the specified file
Can anyone please tell me why NamedPipeClientStream.Connect() would throw a System.IO.FileNotFoundException exception (Unable to find the specified file)? 任何人都可以告诉我为什么NamedPipeClientStream.Connect()会抛出System.IO.FileNotFoundException异常(无法找到指定的文件)? I thought the Connect() method will just block forever rather than throwing an exception.
我认为Connect()方法将永远阻止而不是抛出异常。
Thank you in advance! 先感谢您!
NamedPipeClientStream.Connect()
is just managed wrapper over WaitNamedPipe
and CreateFile
kernel method. NamedPipeClientStream.Connect()
只是WaitNamedPipe
和CreateFile
内核方法的托管包装器。
More here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365800(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx 更多信息: https : //msdn.microsoft.com/en-us/library/windows/desktop/aa365800( v = vs。85) 。aspx https://msdn.microsoft.com/en-us/library/windows /desktop/aa363858(v=vs.85).aspx
The managed part looks like (simplified): 托管部分看起来像(简化):
public void Connect(int timeout = -1) {
int tickCount = Environment.TickCount;
int elapsed = 0;
SafePipeHandle safePipeHandle;
while (true) {
if (!WaitNamedPipe(normalizedPipePath, timeout - elapsed)) {
int lastWin32Error = Marshal.GetLastWin32Error();
if (lastWin32Error != FILE_NOT_FOUND && lastWin32Error != SUCCESS) {
ThrowWinIOError(lastWin32Error, string.Empty);
}
}
if (timeout != -1 && (elapsed = Environment.TickCount - tickCount) >= timeout) {
throw new TimeoutException();
}
safePipeHandle = CreateFile(normalizedPipePath, m_access, FileShare.None, null, FileMode.Open, num, null);
if (!safePipeHandle.IsInvalid) {
// success
return;
}
int lastWin32Error2 = Marshal.GetLastWin32Error();
if (lastWin32Error2 == PIPE_BUSY) {
continue;
}
ThrowWinIOError(lastWin32Error2, string.Empty);
}
}
So it invokes WaitNamedPipe
which returns immediatelly if pipe doesn't exist and managed code does the retry (it retries indefinetly if no timeout is specified). 所以它调用
WaitNamedPipe
,如果管道不存在则会立即返回,并且托管代码会重试(如果没有指定超时,它将无条件地重试)。 Tricky part is that CreateFile
does no handling of FILE_NOT_FOUND error (it handles just PIPE_BUSY error) - I suspect this is where you can run into racial condition. 棘手的部分是
CreateFile
没有处理FILE_NOT_FOUND错误(它只处理PIPE_BUSY错误) - 我怀疑这是你可以遇到种族状况的地方。
IE: WaitNamedPipe
returns ok, but before CreateFile
is hit the pipe changed (went back to void after hibernation ?) and CreateFile
throws exception you're seeing. IE:
WaitNamedPipe
返回ok,但是在CreateFile
被点击之前管道发生了变化(休眠后又回到了无效状态?)并且CreateFile
会抛出你看到的异常。
Workaround should be relatively simple - wrap Connect
method to retry on FILE_NOT_FOUND IOException
. 解决方法应该相对简单 - 将
Connect
方法包装在FILE_NOT_FOUND IOException
上重试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.