对于 C# 应用程序之间的双向数据交换,我使用命名管道。 App-1 是管道服务器,App-2 是客户端。 当在 App-1 中单击按钮时,将执行 pipeline_server 方法,并且 App-1 中的服务器正在等待来自 App-2 的连接。第一次单击按钮后,一切都按预期进行。 App-2 连接并向 App-1 发送数据。
每次数据传输后,我都会处理管道服务器。我希望每次单击新按钮都会生成一个新的管道流,并且数据传输像以前一样从头开始运行。但第二次单击按钮后,我总是收到“System.ObjectDisposeException:无法访问关闭的管道”。在服务器端。我认为我在服务器端处理管道流时犯了一些错误。
服务器端(App-1)
public string test = "";
public StreamReader sr ;
public StreamWriter sw ;
public NamedPipeServerStream pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 20, 20);
public void pipe_server // executed on button click
{
CancellationTokenSource source = new CancellationTokenSource();
server_named_pipe(source.Token);
}
protected async Task server_named_pipe(CancellationToken stoppingToken)
{
PipeSecurity ps = new PipeSecurity();
System.Security.Principal.SecurityIdentifier sid = new System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.WorldSid, null);
PipeAccessRule par = new PipeAccessRule(sid, PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow);
ps.AddAccessRule(par);
sr = new StreamReader(pipeServer);
sw = new StreamWriter(pipeServer);
try
{
var asyncResult = pipeServer.BeginWaitForConnection(PipeConnected, this);
if (asyncResult.AsyncWaitHandle.WaitOne(5000))
{
pipeServer.EndWaitForConnection(asyncResult);
// ...
}
}
catch (Exception ex)
{
//throw ex;
pipeServer.WaitForPipeDrain();
if (pipeServer.IsConnected)
{
pipeServer.Disconnect();
}
}
finally
{
if (sw != null) sw.Dispose();
if (sr != null) sr.Dispose();
pipeServer.Dispose();
}
}
}
public void PipeConnected(IAsyncResult e)
{
sw.WriteLine("Waiting");
sw.Flush();
pipeServer.WaitForPipeDrain();
test = sr.ReadLine();
using (StreamWriter sw2 = File.AppendText(CommonClass.error_path))
{
sw2.WriteLine("Named_Pipe_message: " + " " + test + Convert.ToString(DateTime.Now) + " ");
}
}
每次数据传输后,我都会处理管道服务器。
您应该重新创建服务器。您(通常)不能使用已处置的资源。至少在处理后重新创建
NamedPipeServerStream
。例如:
public NamedPipeServerStream pipeServer;
protected async Task server_named_pipe(CancellationToken stoppingToken)
{
pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 20, 20);
sr = new StreamReader(pipeServer);
sw = new StreamWriter(pipeServer);
}