gpt4 book ai didi

C#: Asynchronous NamedPipeServerStream The pipe is being closed 异常

转载 作者:太空狗 更新时间:2023-10-30 00:15:45 26 4
gpt4 key购买 nike

我之前关于同一主题的问题:C#: Asynchronous NamedPipeServerStream understanding现在我有下一个:

private void StartListeningPipes()
{
try
{
isPipeWorking = true;
namedPipeServerStream = new NamedPipeServerStream(PIPENAME, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, BUFFERSIZE, BUFFERSIZE);
Console.Write("Waiting for client connection...");
while(isPipeWorking)
{
IAsyncResult asyncResult = namedPipeServerStream.BeginWaitForConnection(this.WaitForConnectionAsyncCallback, null);
Thread.Sleep(3*1000);
}
}
//// Catch the IOException that is raised if the pipe is broken or disconnected.
catch (IOException e)
{
Console.WriteLine("IOException: {0}. Restart pipe server...", e.Message);
StopListeningPipes();
StartListeningPipes();
}
//// Catch ObjectDisposedException if server was stopped. Then do nothing.
catch (ObjectDisposedException)
{
}
}

private void WaitForConnectionAsyncCallback(IAsyncResult result)
{
try
{
namedPipeServerStream.EndWaitForConnection(result);
Console.WriteLine("Client connected.");
namedPipeServerStream.WaitForPipeDrain();
byte[] buff = new byte[BUFFERSIZE];
namedPipeServerStream.Read(buff, 0, BUFFERSIZE);
string recStr = TrimNulls(buff);
Array.Clear(buff, 0, buff.Length);
Console.WriteLine();
Console.WriteLine("'"+recStr+"'");
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
}

但是我得到了

管道正在关闭异常 每次我收到来自客户端的消息

为什么?

我的客户:

 using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(General.PIPENAME))
{
try
{
byte[] bytes = General.Iso88591Encoding.GetBytes(sendingMessage);
pipeStream.Write(bytes, 0, bytes.Length);
pipeStream.Flush();
pipeStream.WaitForPipeDrain();
}
catch (TimeoutException)
{
Console.WriteLine("Timeout error!");
}
catch (Exception e)
{
Console.WriteLine(string.Format("Error! ", e.Message));
}
}

目前的最终代码是:

/// <summary>
/// Create new NamedPipeServerStream for listening to pipe client connection
/// </summary>
private void ListenForPipeClients()
{
if (!this.isListeningToClients)
return;

try
{
PipeSecurity ps = new PipeSecurity();
PipeAccessRule par = new PipeAccessRule("Everyone", PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow);
ps.AddAccessRule(par);
pipeClientConnection = new NamedPipeServerStream(General.PIPENAME, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, General.BUFFERSIZE, General.BUFFERSIZE, ps);
Console.Write("Waiting for client connection...");
/*namedPipeServerStream.WaitForConnection();
OnPipeConnected(namedPipeServerStream);*/
IAsyncResult result = pipeClientConnection.BeginWaitForConnection(OnPipeConnected, pipeClientConnection);
}
catch (ObjectDisposedException)
{
//// Catch ObjectDisposedException if server was stopped. Then do nothing.
}
catch (Exception e)
{
Console.WriteLine("Error occures: {0}. Restart pipe server...", e.Message);
this.logger.Add(LogLevel.Warning, string.Format("Error occures: {0}. Restart pipe server...", e.Message));
ListenForPipeClients();
}
}

/// <summary>
/// Async callback on client connected action
/// </summary>
/// <param name="asyncResult">Async result</param>
private void OnPipeConnected(IAsyncResult asyncResult)
{
using (var conn = (NamedPipeServerStream)asyncResult.AsyncState)
{
try
{
conn.EndWaitForConnection(asyncResult);
Console.WriteLine("Client connected.");
PipeClientConnection clientConnection = new PipeClientConnection(conn, notifierSenderCache, defaultStorageTime);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
this.logger.Add(LogLevel.Warning, e.Message);
}
}

ListenForPipeClients();
}

最佳答案

您似乎需要为每个客户端使用单独的 NamedPipeServerStream。 (请注意,我不是发现这一点的人,请参阅其他答案。)我想象工作服务器端看起来像这样(代码草案):

while(this.isServerRunning)
{
var pipeClientConnection = new NamedPipeServerStream(...);

try
{
pipeClientConnection.WaitForConnection();
}
catch(...)
{
...
continue;
}

ThreadPool.QueueUserWorkItem(state =>
{
// we need a separate variable here, so as not to make the lambda capture the pipeClientConnection variable, which is not recommended in multi-threaded scenarios
using(var pipeClientConn = (NamedPipeServerStream)state)
{
// do stuff
...
}
}, pipeClientConnection);
}

作为旁注,正如在对您的问题的评论中指出的那样,通过在循环中调用 BeginWaitForConnection 每 3 秒启动一次新的异步调用是在浪费内存(唯一这不会浪费内存的情况是在小于 3 秒的时间间隔内建立新连接,但我怀疑你能肯定地知道这一点)。您会看到,基本上每 3 秒您就会启动一个新的异步调用,而不管最后一个调用是否仍在等待或已完成。此外,它再次没有考虑到您需要为每个客户端使用单独的 NamedPipeServerStream

要解决此问题,您需要消除循环,并使用回调方法“链接”BeginWaitForConnection 调用。这是您在使用 .NET 时经常在异步 I/O 中看到的类似模式。代码草稿:

private void StartListeningPipes()
{
if(!this.isServerRunning)
{
return;
}

var pipeClientConnection = new NamedPipeServerStream(...);

try
{
pipeClientConnection.BeginWaitForConnection(asyncResult =>
{
// note that the body of the lambda is not part of the outer try... catch block!
using(var conn = (NamedPipeServerStream)asyncResult.AsyncState)
{
try
{
conn.EndWaitForConnection(asyncResult);
}
catch(...)
{
...
}

// we have a connection established, time to wait for new ones while this thread does its business with the client
// this may look like a recursive call, but it is not: remember, we're in a lambda expression
// if this bothers you, just export the lambda into a named private method, like you did in your question
StartListeningPipes();

// do business with the client
conn.WaitForPipeDrain();
...
}
}, pipeClientConnection);
}
catch(...)
{
...
}
}

控制流程是这样的:

  • [主线程] StartListeningPipes():创建了NamedPipeServerStream,启动了BeginWaitForConnection()
  • [线程池线程 1] 客户端 #1 连接,BeginWaitForConnection() 回调:EndWaitForConnection() 然后 StartListeningPipes()
  • [线程池线程 1] StartListeningPipes():创建了新的 NamedPipeServerStream,BeginWaitForConnection() 调用
  • [线程池线程 1] 回到 BeginWaitForConnection() 回调:开始处理连接的客户端(#1)
  • [线程池线程 2] 客户端 #2 连接,BeginWaitForConnection() 回调:...
  • ...

我认为这比使用阻塞 I/O 困难得多 - 事实上,我不太确定我做对了,如果你看到任何错误请指出 - 而且它也更令人困惑.

要在任一示例中暂停服务器,您显然需要将 this.isServerRunning 标志设置为 false

关于C#: Asynchronous NamedPipeServerStream The pipe is being closed 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11450522/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com