管道正在关闭异常
本文关键字:异常 管道 | 更新日期: 2023-09-27 18:22:46
有时,在某些机器上,使用我的程序的客户端会出现"管道正在关闭"异常。这种情况发生在.WWaitForConnection()上的NamedPipeServerStream上。之后,应用程序完全崩溃并释放一个windows异常。当NamedPipeClientStream将信息传输到独立应用程序时,就会发生这种情况。
主要功能:我写了几个工具(Office工具栏、一个服务、一个独立的.net应用程序和一个litle starter exe),它们与NamedPipes一起通信。该服务运行一个始终打开的NamedPipeServerStream(状态为.WWaitForConnection();)并且独立应用程序也具有NamedPipeServerStream。工具栏和starter.exe与服务通信。然后使用独立应用程序的服务。
什么样的问题可以释放正在关闭的管道异常?服务器是否可能向独立应用程序发送信息,但由于独立应用程序未准备好或其他原因而提前关闭流?在每个NamedPipeClientStream上,如果pipeClient.IsConnected,我会在关闭pipeClient之前等待管道排水。。
感谢的帮助
edit:这里是一个客户端流的例子
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", pipename, PipeDirection.Out))
{
// Wait for a client to connect
try
{
pipeClient.Connect(3000);
// send params to the form
using (StreamWriter sw = new StreamWriter(pipeClient))
{
sw.AutoFlush = true;
sw.WriteLine(sendtext);
}
}
// Catch the IOException that is raised if the pipe is
// broken or disconnected.
catch (Exception e)
{
if (sid != "")
{
connections.Remove(conName);
}
eventLog1.WriteEntry("SendText Fehler 1 " + e.Message);
}
finally
{
if (pipeClient.IsConnected)
{
pipeClient.WaitForPipeDrain();
}
pipeClient.Close();
pipeClient.Dispose();
}
管道服务器(在seperad线程中运行)的示例
NamedPipeServerStream pipeServer;
PipeSecurity pipe_security = CreateSystemIoPipeSecurity();
do
string pipename = global::TOfficeCenter.Properties.Settings.Default.pipename;
string aText = "";
pipeServer = new NamedPipeServerStream(pipename, PipeDirection.In, ONE_INSTANCE, PipeTransmissionMode.Byte,
PipeOptions.None, IN_BUF_SIZE, OUT_BUF_SIZE, pipe_security);
try
{
// Verbindung zu TOfficeCenter.exe aufbauen
try
{
IsWaiting = true;
pipeServer.WaitForConnection();
IsWaiting = false;
using (StreamReader sr = new StreamReader(pipeServer))
{
string temp;
while ((temp = sr.ReadLine()) != null)
{
aText = aText + temp;
}
}
try
{
if (aText == "")
{
empfang(null);
}
else
{
if (aText != "KillPipe")
{ // XML empfangen
XmlDocumentTC xml = new XmlDocumentTC();
xml.LoadXml(aText);
empfang(xml);
}
}
}
catch (Exception)
{
empfang(null);
}
}
catch
{...........
}
}
catch (Exception e)
{...........
}
} while (running);
pipeServer.Close();
我可能终于找到了问题。。
我发现在这个代码之后:
using (StreamWriter sw = new StreamWriter(pipeClient))
{
sw.AutoFlush = true;
sw.WriteLine(sendtext);
}
管道Client.IsConnected();直接返回false,因此它永远不会到达WaitForPipeDrain。我现在这样做了,希望客户端在服务器完成读取之前不要关闭连接。。
using (StreamWriter sw = new StreamWriter(pipeClient))
{
sw.AutoFlush = true;
sw.WriteLine(sendtext);
pipeClient.WaitForPipeDrain();
}
你认为这能解决问题吗?自从我这么做以来,我从未在两台测试机上出现过错误。但是错误很少发生。。
我的使用有点不同,但我将把服务器线程包括在内,因为它目前主要是从MSDN页面被黑客入侵的:
MSDN:如何使用命名管道
不确定我是否需要"WaitForPipeToDrain()",但我从你的代码中获取了它:)
我认为每次重置pipeServer都会清理我的IOException。
int threadId = Thread.CurrentThread.ManagedThreadId;
bool sentinel = true;
while (sentinel)
{
NamedPipeServerStream pipeServer =
new NamedPipeServerStream("shapspipe", PipeDirection.InOut, 1);
// Wait for a client to connect
pipeServer.WaitForConnection();
Console.WriteLine("Client connected on thread[{0}].", threadId);
try
{
// Read the request from the client. Once the client has
// written to the pipe its security token will be available.
StreamString ss = new StreamString(pipeServer);
// Verify our identity to the connected client using a
// string that the client anticipates.
ss.WriteString("I am the one true server!");
string message = ss.ReadString();
Console.WriteLine("received from client: " + message);
ss.WriteString("echo from server: " + message);
Console.WriteLine("Received from client: {0} on thread[{1}] as user: {2}.",
message, threadId, pipeServer.GetImpersonationUserName());
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
pipeServer.WaitForPipeDrain();
pipeServer.Close();
}