C#管道通讯及传输信息丢失的原因

以下是C#管道通讯客户端/服务端共用类

namespace PipeCommunication

{

/// <summary>

/// 管道信息回调通知

/// </summary>

/// <param name="msg"></param>

public delegate void PipeMessageEventHandler(string msg);

public class PipeCommunicateCenter

{

public event PipeMessageEventHandler OnPipeMessageReceiveEvent;

private string _pipeServerName = "";

private string _pipeClientName = "";

public PipeCommunicateCenter(string pipeServerName, string pipeClientName)

{

_pipeServerName = pipeServerName;

_pipeClientName = pipeClientName;

}

/// <summary>

/// 发送消息

/// </summary>

/// <param name="msg"></param>

public void ClientSend(string msg)

{

try

{

using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", _pipeClientName, PipeDirection.InOut))

{

pipeClient.Connect(3000);

using (StreamWriter sw = new StreamWriter(pipeClient))

{

sw.AutoFlush = true;

sw.WriteLine(msg);

}

}

}

catch (Exception ex)

{

}

}

Thread thPipLsiten;

/// <summary>

/// 启动监听

/// </summary>

public void StartPipListen()

{

thPipLsiten = new Thread(PipListen);

thPipLsiten.IsBackground = true;

thPipLsiten.Start();

}

/// <summary>

/// 监听线程是否存在

/// </summary>

/// <returns></returns>

public bool GetPipListenIsAlive()

{

return thPipLsiten == null ? false : thPipLsiten.IsAlive;

}

bool hasRead = false;

/// <summary>

/// 监听线程

/// </summary>

private void PipListen()

{

try

{

while (!isExist)

{

using (NamedPipeServerStream pipeServer = new NamedPipeServerStream(_pipeServerName, PipeDirection.InOut))

{

pipeServer.WaitForConnection();//等待连接,程序会阻塞在此处,直到有一个连接到达

hasRead = false;

try

{

while (!hasRead)

{

using (StreamReader sr = new StreamReader(pipeServer))

{

var read = sr.ReadLine();

if (!string.IsNullOrEmpty(read))

{

hasRead = true;

//MessageBox.Show("pipread:" + read);

NotifyPipeMessageReceive(read);

}

}

Thread.Sleep(10);

}

}

catch (Exception ex2)

{

}

}

Thread.Sleep(10);

}

}

catch (Exception ex1)

{

}

}

/// <summary>

/// 通知收到信息

/// </summary>

/// <param name="msg"></param>

private void NotifyPipeMessageReceive(string msg)

{

OnPipeMessageReceiveEvent?.Invoke(msg);

}

bool isExist = false;

/// <summary>

/// 退出监听管道

/// </summary>

public void ExistPipeCommunicate()

{

isExist = true;

}

}

}

使用条件:

客户端/服务端通讯均在线程中使用

问题:

在使用过程中偶尔发生通讯丢失,程式假死,程式逻辑无法正常走下去.

原因分析:

因为程式中异步线程使用了Application.DoEvents()方法.

在C# WinForms中,Application.DoEvents() 方法的作用是强制处理当前消息队列中的所有Windows消息,例如用户输入(点击、键盘事件)、界面重绘等。它的主要意义是让应用程序在长时间运行的代码中保持界面响应,但需谨慎使用。

当执行耗时操作(如循环、复杂计算或阻塞任务)时,UI线程会被占用,导致界面"卡死"(无法响应用户操作或更新显示)。调用 Application.DoEvents() 会临时处理消息队列中的事件,让界面保持"假响应"。

解决方案:

在非UI线程中禁止使用 Application.DoEvents()

异步线程强制使用 Application.DoEvents()可能会导致事件处理顺序混乱,界面更新异常,逻辑依赖破坏等问题.

相关推荐
宝桥南山15 小时前
GitHub Models - 尝试一下使用GitHub Models
microsoft·ai·微软·c#·github·.netcore
hixiong12317 小时前
C# OpenvinoSharp部署INSID3
开发语言·人工智能·ai·c#·openvinosharp
星辰徐哥18 小时前
Unity C#入门:变量的定义与访问权限(public/private)
unity·c#·lucene
leoufung18 小时前
LeetCode 30:Substring with Concatenation of All Words 题解(含 C 语言 uthash 实现)
c语言·leetcode·c#
hacker70719 小时前
Visual Studio安装教程(C#开发版)
ide·c#·visual studio
SKY -dada19 小时前
Understand 使用教程
开发语言·c#·流程图·软件构建·敏捷流程·代码复审·源代码管理
William_cl21 小时前
【C#/.NET 进阶】ASP.NET 架构与最佳实践:DI 依赖注入(IoC 核心)从入门到避坑
c#·asp.net·.net
武藤一雄21 小时前
WPF:MessageBox系统消息框
前端·microsoft·c#·.net·wpf
武藤一雄21 小时前
WPF进阶:万字详解WPF如何性能优化
windows·性能优化·c#·.net·wpf·.netcore·鲁棒性
xiaogutou11212 天前
2026年历史课件PPT模板选购指南:教师备课效率与精度的平衡方案
开发语言·c#