C#进程通讯-命名管道通讯

目录

客户端代码

csharp 复制代码
Task.Run(() =>
            {
                List<string> result = new List<string>();

                try
                {
                    using (var client = new NamedPipeClientStream(".", "MyTranslatePipe", PipeDirection.InOut))
                    {
                        // 记录连接开始(便于调试)
                        System.Diagnostics.Debug.WriteLine("NamedPipe: Connecting...");
                        // 5 秒超时(根据需要调整)
                        client.Connect(5000);
                        System.Diagnostics.Debug.WriteLine($"NamedPipe: Connected = {client.IsConnected}");

                        if (!client.IsConnected)
                        {
                            throw new InvalidOperationException("未能连接到命名管道。请确认服务已启动。");
                        }

                        // 明确使用不带 BOM 的 UTF8,避免可能的前导字节问题
                        var noBomUtf8 = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

                        // 使用 leaveOpen:true,避免 StreamReader/StreamWriter 在 Dispose 时关闭底层 pipe
                        using (var writer = new StreamWriter(client, noBomUtf8, bufferSize: 1024, leaveOpen: true) { AutoFlush = true })
                        using (var reader = new StreamReader(client, noBomUtf8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
                        {
                            System.Diagnostics.Debug.WriteLine("NamedPipe: Writing request...");
                            writer.WriteLine(json);
                            writer.Flush();

                            System.Diagnostics.Debug.WriteLine("NamedPipe: Waiting for response...");
                            // 阻塞读取一行响应(服务端必须 WriteLine 返回)
                            string resultJson = reader.ReadLine();
                            System.Diagnostics.Debug.WriteLine("NamedPipe: Received response");

                            if (string.IsNullOrEmpty(resultJson))
                            {
                                // 防护:避免反序列化 null 抛异常
                                result = new List<string>();
                            }
                            else
                            {
                                result = JsonConvert.DeserializeObject<List<string>>(resultJson) ?? new List<string>();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // 记录并用简单回退策略,不抛到 UI 线程导致不可预期的问题
                    System.Diagnostics.Debug.WriteLine("NamedPipe error: " + ex);
                    try
                    {
                        // 在 AutoCAD 环境建议用 Editor.WriteMessage 打日志(此处用 MessageBox 仅作提示)
                        System.Windows.MessageBox.Show("翻译服务通信失败:" + ex.Message, "提示");
                    }
                    catch { /* 若线程上下文不能弹窗则忽略 */ }

                    // 回退到原文,保证不会返回 null
                    result = texts.ToList();
                }

                return result;
            });

服务端

csharp 复制代码
using Newtonsoft.Json;
using System.IO.Pipes;
using System.Text;
using System.Threading.Tasks;
using TextTranslate;

Console.WriteLine("Named pipe server starting...");

string pipeName = "MyTranslatePipe";

// 使用异步主循环,持续接受客户端连接
while (true)
{
    // 为每次连接创建新的 NamedPipeServerStream,但不要在外层 using,这样不会在启动后台任务后立即被释放
    var server = new NamedPipeServerStream(
        pipeName,
        PipeDirection.InOut,
        NamedPipeServerStream.MaxAllowedServerInstances,
        PipeTransmissionMode.Byte,
        PipeOptions.Asynchronous);

    Console.WriteLine("等待 .NET Framework 客户端连接...");
    await server.WaitForConnectionAsync();
    Console.WriteLine("客户端已连接。");

    // 为当前连接启动一个后台任务来处理(任务内部负责释放 server)
    _ = Task.Run(async () =>
    {
        // 将 server 的释放放到任务内部 using,确保后台任务结束后再释放
        using (server)
        {
            try
            {
                var noBomUtf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

                // 使用 leaveOpen:true,防止 reader/writer 在 Dispose 时关闭底层 NamedPipeServerStream
                using var reader = new StreamReader(server, noBomUtf8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true);
                using var writer = new StreamWriter(server, noBomUtf8, bufferSize: 1024, leaveOpen: true) { AutoFlush = true };

                while (server.IsConnected)
                {
                    string? request = await reader.ReadLineAsync();

                    if (request == null)
                    {
                        Console.WriteLine("客户端已断开连接(read null)。");
                        break;
                    }

                    if (string.IsNullOrEmpty(request) || request.Equals("exit", StringComparison.OrdinalIgnoreCase))
                    {
                        Console.WriteLine("收到退出指令,关闭连接。");
                        break;
                    }

                    Console.WriteLine($"收到请求: {request}");

                    string result = Translate(request);

                    await writer.WriteLineAsync(result);
                    Console.WriteLine($"返回结果: {result}");
                }

                // 确保所有写入被刷新到管道
                try { writer.Flush(); } catch { }
            }
            catch (Exception ex)
            {
                Console.WriteLine("处理客户端时发生异常: " + ex);
            }
            finally
            {
                // 显式断开连接(断开前 reader/writer 已被 Dispose,但 leaveOpen:true 不会关闭底层 stream)
                try { if (server.IsConnected) server.Disconnect(); } catch { }
                Console.WriteLine("处理任务结束,准备接受下一个连接。");
            }
        }
    });
}

static string Translate(string input)
{
    TranslationRequest? translationRequest = JsonConvert.DeserializeObject<TranslationRequest>(input);
    Task<List<string>> task = translationRequest.Texts.Translate(translationRequest.TargetLanguage);
    task.Wait();
    return JsonConvert.SerializeObject(task.Result);
    //return JsonConvert.SerializeObject(new List<string>() { "苹果" });

}

// 内部请求模型(与服务端保持一致)
public class TranslationRequest
{
    public List<string> Texts { get; set; }
    public string TargetLanguage { get; set; }
}
相关推荐
滴滴答答哒1 小时前
# SqlSugar 差异日志功能实现
c#
顾温2 小时前
协程结束——实测
开发语言·unity·c#
唐青枫4 小时前
C#.NET YARP 详解:用 ASP.NET Core 打造高性能反向代理网关
c#·.net
asdzx674 小时前
告别手工复制:用 C# 轻松合并多份 Word
c#·word
步步为营DotNet5 小时前
NET 11 中 C# 14 新特性在云原生微服务架构的深度实践
云原生·架构·c#
不会编程的懒洋洋6 小时前
WPF 性能优化+异步+渲染
开发语言·笔记·性能优化·c#·wpf·图形渲染·线程
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ18 小时前
通过java后端代码来实现给word内容补充格式文本内容控件,以及 设置控件的标记和标题
java·c#·word
Hesionberger1 天前
LeetCode79:单词搜索DFS回溯详解
java·开发语言·c++·python·算法·leetcode·c#
曹牧1 天前
C#:同一项目中维护多个版本的代码
开发语言·c#
工程师0071 天前
C# UI 跨线程刷新:Invoke/BeginInvoke 原理与封装
c#·invoke·begininvoke