对于我的C#应用程序之间的双向数据交换,我使用命名管道. App-1是管道服务器,App-2是客户端. 当点击App-1中的按钮时,将执行PIPE_SERVER方法和App-1,因为服务器正在等待来自App-2的连接.第一次点击该按钮后,一切都按预期进行.App-2连接并向App-1发送数据.

在每次数据传输之后,我要处理管道服务器.我希望每次单击新按钮都会生成一个新的管道流,并且数据传输像以前一样从头开始运行.但在第二次单击该按钮后,我总是会看到"System.ObjectDisposedException:Cannot Access a Closed Pipes".在服务器端.我想我在服务器端处理pipestream时出了点问题.

服务器端(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(就像对StreamReader/StreamWriter所做的那样).例如:

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);
    // ...
}

就个人而言,您将删除pipeServersrsr字段,并将所有处理移到server_named_pipe方法中.

Csharp相关问答推荐

EF Core在请求列表时忽略列,但在按ID获取时包含

如何使用XmlSerializer反序列化字符串数组?

Polly v8—使用PredicateBuilder重试特定的状态代码

用C#调用由缓冲区指针参数组成的C API

如何使用MoQ模拟Resources GroupCollection?

RabbitMQ群集的MassTransit配置问题

Google OAuth令牌交换在.Net中不起作用

在C#中,是否有与变量DISARD对应的C++类似功能?

无法使用[FromForm]发送带有图像和JSON的多部分请求

使用C#和.NET 7.0无法访问Cookie中的数据

如何在同一成员上组合[JsonPropertyName]和[ObservableProperty]?

为什么我不能从我的异步任务方法中返回异步任务方法?

.NET8Blazor-为什么Rapzor渲染在for循环之后显示?

在构造函数中传递C#函数以用作EventHandler委托的订阅服务器

在.NET Maui中,Flyoutindow/Hamburger菜单可以在shell 之外实现吗?

Linq SELECT的多条指令

使用免费的DotNet库从Azure函数向Azure文件共享上的现有Excel文件追加行

实例化列表时的集合表达式是什么?

使用ImmutableList时,DynamicData未按预期工作

MudRadioGroup不切换