如何让命名管道在 C# 中阻塞?
How do I get a Named Pipe to block in C#?
我正在编写一个 C# Windows 服务 (server),它需要从 C++ GUI 应用程序 (clients[=39] 接收消息=]) 很少使用 命名管道 ;可能需要几天到几周的时间才能收到消息。在我的测试中,我注意到它没有阻止数据进入,而是不断检查并打印换行符。它确实收到了测试消息,但我不得不使用 Visual Studio 中的调试器来验证。
有没有办法让 C# 部分阻塞,直到实际接收到数据?
--C#代码:
var client = new NamedPipeServerStream("PipeTest");
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
while (true)
{
Console.WriteLine(reader.ReadLine());
}
--C++代码:
DWORD written;
INT error_code;
CHAR buffer[1024];
LPCWSTR pipe_name = L"\\.\pipe\PipeTest";
LRESULT result;
WaitNamedPipe(pipe_name, NMPWAIT_WAIT_FOREVER);
HANDLE hpipe = CreateFile(pipe_name,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
error_code = GetLastError();
sprintf_s(buffer,"Sending Test Message");
WriteFile(hpipe,buffer,strlen(buffer),&written,NULL);
result = GetLastError();
fprintf(stdout,"Pipe: %d Write: %d Written: %d",error_code,result,written);
DisconnectNamedPipe(hpipe);
CloseHandle(hpipe);
std::cin.get();
[答案]
--C#代码(server)更正名称:
var server = new NamedPipeServerStream("PipeTest");
while (true)
{
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
Console.WriteLine(reader.ReadLine());
server.Disconnect();
}
对于这段代码,我只需要捕获一行数据,@The Shooter 是正确的,但您需要添加 server.Disconnect()
才能再次阅读。我从 C documentation 中找到了这个,同样的原理显然适用于 C#。
The server process must call DisconnectNamedPipe
to disconnect a pipe handle from its previous client before the handle can be connected to another client by using the ConnectNamedPipe
function.
客户端正在断开管道,因此服务器在收到测试消息后立即看到输入流的结尾。
StreamReader.ReadLine() 的文档说:
The next line from the input stream, or null if the end of the input stream is reached.
所以 ReadLine
正在返回 null
; Console.WriteLine(String) 在这种情况下会做什么?
If value is null, only the line terminator is written to the standard output stream.
QED。您看到的行为完全符合预期。
您需要检查从 ReadLine
返回的值并适当地处理 null
。在这种情况下,您可能想等待另一个连接。
而不是:
var client = new NamedPipeServerStream("PipeTest");
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
while (true)
{
Console.WriteLine(reader.ReadLine());
}
试试这个:
var client = new NamedPipeServerStream("PipeTest");
while (true)
{
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
Console.WriteLine(reader.ReadLine());
}
我正在编写一个 C# Windows 服务 (server),它需要从 C++ GUI 应用程序 (clients[=39] 接收消息=]) 很少使用 命名管道 ;可能需要几天到几周的时间才能收到消息。在我的测试中,我注意到它没有阻止数据进入,而是不断检查并打印换行符。它确实收到了测试消息,但我不得不使用 Visual Studio 中的调试器来验证。
有没有办法让 C# 部分阻塞,直到实际接收到数据?
--C#代码:
var client = new NamedPipeServerStream("PipeTest");
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
while (true)
{
Console.WriteLine(reader.ReadLine());
}
--C++代码:
DWORD written;
INT error_code;
CHAR buffer[1024];
LPCWSTR pipe_name = L"\\.\pipe\PipeTest";
LRESULT result;
WaitNamedPipe(pipe_name, NMPWAIT_WAIT_FOREVER);
HANDLE hpipe = CreateFile(pipe_name,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
error_code = GetLastError();
sprintf_s(buffer,"Sending Test Message");
WriteFile(hpipe,buffer,strlen(buffer),&written,NULL);
result = GetLastError();
fprintf(stdout,"Pipe: %d Write: %d Written: %d",error_code,result,written);
DisconnectNamedPipe(hpipe);
CloseHandle(hpipe);
std::cin.get();
[答案]
--C#代码(server)更正名称:
var server = new NamedPipeServerStream("PipeTest");
while (true)
{
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
Console.WriteLine(reader.ReadLine());
server.Disconnect();
}
对于这段代码,我只需要捕获一行数据,@The Shooter 是正确的,但您需要添加 server.Disconnect()
才能再次阅读。我从 C documentation 中找到了这个,同样的原理显然适用于 C#。
The server process must call
DisconnectNamedPipe
to disconnect a pipe handle from its previous client before the handle can be connected to another client by using theConnectNamedPipe
function.
客户端正在断开管道,因此服务器在收到测试消息后立即看到输入流的结尾。
StreamReader.ReadLine() 的文档说:
The next line from the input stream, or null if the end of the input stream is reached.
所以 ReadLine
正在返回 null
; Console.WriteLine(String) 在这种情况下会做什么?
If value is null, only the line terminator is written to the standard output stream.
QED。您看到的行为完全符合预期。
您需要检查从 ReadLine
返回的值并适当地处理 null
。在这种情况下,您可能想等待另一个连接。
而不是:
var client = new NamedPipeServerStream("PipeTest");
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
while (true)
{
Console.WriteLine(reader.ReadLine());
}
试试这个:
var client = new NamedPipeServerStream("PipeTest");
while (true)
{
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
Console.WriteLine(reader.ReadLine());
}