如何在C#中获得要阻塞的命名管道
本文关键字:管道 | 更新日期: 2023-09-27 17:59:03
我正在编写一个C#Windows服务(服务器),该服务需要很少使用命名管道接收来自C++GUI应用程序(client的消息;收到消息可能需要几天到几周的时间。在我的测试中,我注意到它并没有阻止数据进入,而是不断地检查和打印换行符。它确实收到了测试消息,但我不得不使用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文档中发现了这一点,显然同样的原理在C#中也适用。
服务器进程必须调用
DisconnectNamedPipe
以断开管道句柄与其前一个客户端的连接,然后才能使用ConnectNamedPipe
函数将句柄连接到另一个客户端。
客户端正在断开管道连接,因此服务器在收到测试消息后立即看到输入流的结束。
StreamReader的文档。ReadLine()表示:
输入流的下一行,如果到达输入流的末尾,则为null。
所以ReadLine
正在返回null
;Console做什么。WriteLine(String)在这种情况下做什么?
如果值为null,则只将行终止符写入标准输出流。
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());
}