You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#命名管道服务端如何设置连接等待超时?

解决NamedPipeServerStream等待连接超时问题

要实现5秒超时停止等待,核心是替换阻塞的WaitForConnection()调用,改用支持超时控制的异步等待方式,以下是两种可行方案:

方案一:使用异步方法+超时任务(推荐,适配多数.NET版本)

利用WaitForConnectionAsync()结合Task.WhenAny实现超时控制,代码修改如下:

public async void server_named_pipe()
{
    const int ConnectionTimeoutMs = 5000; // 5秒超时
    string test = "";
    do
    {
        NamedPipeServerStream pipeServer = null;
        StreamReader sr = null;
        StreamWriter sw = null;
        try
        {
            pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 1, 
                PipeTransmissionMode.Message, PipeOptions.Asynchronous, 20, 20);
            sr = new StreamReader(pipeServer);
            sw = new StreamWriter(pipeServer);

            // 同时等待连接任务和超时任务
            var connectTask = pipeServer.WaitForConnectionAsync();
            var timeoutTask = Task.Delay(ConnectionTimeoutMs);
            var completedTask = await Task.WhenAny(connectTask, timeoutTask);

            if (completedTask == timeoutTask)
            {
                // 超时触发,关闭管道并终止等待
                pipeServer.Close();
                Console.WriteLine("连接超时,停止等待");
                break;
            }

            // 连接成功,执行后续通信逻辑
            await connectTask;
            sw.WriteLine("Waiting");
            await sw.FlushAsync();
            await pipeServer.WaitForPipeDrainAsync();
            test = await sr.ReadLineAsync();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"连接或通信异常: {ex.Message}");
        }
        finally
        {
            sw?.Dispose();
            sr?.Dispose();
            pipeServer?.Dispose();
        }
    } while (string.IsNullOrEmpty(test));
}

关键说明:

  • 将管道、流的创建逻辑移入循环内部,避免单次资源释放后无法复用
  • 通过Task.WhenAny实现“连接/超时”二选一的逻辑,精准控制等待时长
  • 超时后必须主动关闭管道,避免系统资源泄漏
  • 统一使用异步版本的IO方法,保持代码逻辑一致性

方案二:使用旧版异步模型(适配.NET Framework 4.0及更早版本)

如果项目基于较老的.NET Framework,可使用BeginWaitForConnection结合WaitHandle.WaitOne设置超时:

public void server_named_pipe()
{
    const int ConnectionTimeoutMs = 5000;
    string test = "";
    do
    {
        NamedPipeServerStream pipeServer = null;
        StreamReader sr = null;
        StreamWriter sw = null;
        try
        {
            pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 1, 
                PipeTransmissionMode.Message, PipeOptions.Asynchronous, 20, 20);
            sr = new StreamReader(pipeServer);
            sw = new StreamWriter(pipeServer);

            // 启动异步等待连接
            IAsyncResult asyncResult = pipeServer.BeginWaitForConnection(null, null);
            // 等待5秒,判断连接是否完成
            if (!asyncResult.AsyncWaitHandle.WaitOne(ConnectionTimeoutMs))
            {
                pipeServer.Close();
                Console.WriteLine("连接超时,停止等待");
                break;
            }

            // 完成异步连接操作
            pipeServer.EndWaitForConnection(asyncResult);

            sw.WriteLine("Waiting");
            sw.Flush();
            pipeServer.WaitForPipeDrain();
            test = sr.ReadLine();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"连接或通信异常: {ex.Message}");
        }
        finally
        {
            sw?.Dispose();
            sr?.Dispose();
            pipeServer?.Dispose();
        }
    } while (string.IsNullOrEmpty(test));
}

关键说明:

  • 通过BeginWaitForConnection启动异步等待,获取对应的等待句柄
  • 调用WaitOne(ConnectionTimeoutMs)设置超时阈值,返回值表示是否在超时前完成连接
  • 超时后必须关闭管道,避免占用系统句柄资源
  • 连接成功后必须调用EndWaitForConnection完成异步操作流程

内容的提问来源于stack exchange,提问作者Mdarende

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:05:08