我的命名管道在第一次连接后工作正常,但后来我得到 System.ObjectDisposeException:无法访问关闭的管道

问题描述 投票:0回答:1

对于 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) + "   ");

        }            
    }
c# dispose named-pipes
1个回答
0
投票

每次数据传输后,我都会处理管道服务器。

您应该重新创建服务器。您(通常)不能使用已处置的资源。至少在处理后重新创建

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.