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()可能会导致事件处理顺序混乱,界面更新异常,逻辑依赖破坏等问题.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80539.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MixTeX - 支持CPU推理的多模态LaTeX OCR

文章目录 一、项目概览相关资源核心特性技术特点 二、安装三、使用说明环境要求 四、版本更新五、当前限制 一、项目概览 MixTeX是一款创新的多模态LaTeX识别小程序&#xff0c;支持本地离线环境下的高效CPU推理。 无论是LaTeX公式、表格还是混合文本&#xff0c;MixTeX都能轻…

简单 Linux 字符设备驱动程序

注&#xff1a;本文为 “Linux 字符设备驱动” 相关文章合辑。 英文引文&#xff0c;机翻未校。 中文引文&#xff0c;略作重排。 未整理去重&#xff0c;如有内容异常&#xff0c;请看原文。 Simple Linux character device driver 简单 Linux 字符设备驱动程序 Oleg Kutko…

NX949NX952美光科技闪存NX961NX964

NX949NX952美光科技闪存NX961NX964 在半导体存储领域&#xff0c;美光科技始终扮演着技术引领者的角色。其NX系列闪存产品线凭借卓越的性能与创新设计&#xff0c;成为数据中心、人工智能、高端消费电子等场景的核心组件。本文将围绕NX949、NX952、NX961及NX964四款代表性产品…

协议路由与路由协议

协议路由”和“路由协议”听起来相似&#xff0c;但其实是两个完全不同的网络概念。下面我来分别解释&#xff1a; 一、协议路由&#xff08;Policy-Based Routing&#xff0c;PBR&#xff09; ✅ 定义&#xff1a; 协议路由是指 根据预设策略&#xff08;策略路由&#xff0…

Linux510 ssh服务 ssh连接

arning: Permanently added ‘11.1.1.100’ (ECDSA) to the list of known hosts. rooot11.1.1.100’s password: Permission denied, please try again. rooot11.1.1.100’s password: Permission denied, please try again 还没生效 登不上了 失效了 sshcaozx26成功登录 …

金融学知识笔记

金融学知识笔记 一、引言 金融学它结合了数学、概率论、统计学、经济学和计算机科学等多学科的知识&#xff0c;用于解决金融领域中的各种问题&#xff0c;如金融衍生品定价、投资组合优化、风险管理和固定收益证券分析等。通过对金融学的学习&#xff0c;我们可以更好地理解…

AB测试面试题

AB测试面试题 常考AB测试问答题(1)AB测试的优缺点是什么?(2)AB测试的一般流程/介绍一下日常工作中你是如何做A/B实验的?(3)第一类错误 vs 第二类错误 vs 你怎么理解AB测试中的第一、二类错误?(4)统计显著=实际显著?(5)AB测试效果统计上不显著?(6)实验组优于对…

USR-M100采集数据并提交MQTT服务器

本文为记录备忘&#xff0c;不做过多解释。 模块自身带有2路数字量输入&#xff0c;2路模拟量输入&#xff0c;2路485接口 数字量接报警输入&#xff0c;模拟量接压力传感器&#xff0c;液位传感器&#xff0c;485接口分别接流量计&#xff0c;温湿度传感器。 正确接线&…

Octave 绘图快速入门指南

目录 1. 基本的 2D 绘图 2. 自定义图形样式 3. 绘制散点图 4. 绘制柱状图 5. 绘制直方图 6. 3D 绘图 6.6.1 3D 曲面图 6.6.2 3D 散点图 7. 绘制极坐标 8. 多子图绘制 总结 Octave 是一个类似于 MATLAB 的开源数学软件&#xff0c;广泛用于数值计算和数据分析。它提供…

RabbitMQ--基础篇

RabbitMQ 简介&#xff1a;RabbitMQ 是一种开源的消息队列中间件&#xff0c;你可以把它想象成一个高效的“邮局”。它专门负责在不同应用程序之间传递消息&#xff0c;让系统各部分能松耦合地协作 优势&#xff1a; 异步处理&#xff1a;比如用户注册后&#xff0c;主程序将发…

【MySQL】事务(重点)

目录 一、什么是事务&#xff1a; 二、事务的前置知识了解 引擎是否支持事务 事务的提交方式 事务操作的前置准备&#xff1a; 三、事务回滚&#xff1a; 四、事务崩溃&#xff1a; 原子性&#xff1a; 持久性&#xff1a; 五、自动提交和手动提交&#xff1a; 六、…

C++STL——stack,queue

stack与queue 前言容器适配器deque 前言 本篇主要讲解stack与queue的底层&#xff0c;但并不会进行实现&#xff0c;stack的接口 queue的接口 &#xff0c;关于stack与queue的接口在这里不做讲解&#xff0c;因为通过前面的对STL的学习&#xff0c;这些接口都是大同小异的。 …

STM32智能手表:基于FreeRTOS

引言 随着物联网和可穿戴设备的快速发展&#xff0c;智能手表作为典型代表&#xff0c;集成了传感器数据采集、实时显示、无线通信等多项功能。本文将深入剖析一个基于STM32和FreeRTOS的智能手表项目&#xff0c;从硬件架构到软件设计&#xff0c;逐步讲解如何构建一个完整的嵌…

leetcode504.七进制数

标签&#xff1a;进制转换 机试真题 给定一个整数 num&#xff0c;将其转化为 7 进制&#xff0c;并以字符串形式输出。 示例 1: 输入: num 100 输出: "202" 示例 2: 输入: num -7 输出: "-10" 思路&#xff1a;求n进制就是循环取余数&#xff0c;…

中国古代史2

夏朝&#xff08;公元前2070-公元前1600年&#xff09; 1.禹建立了我国历史上第一个奴隶制国家–夏朝&#xff0c;定都阳城。禹传启&#xff0c;世袭制代替禅让制。 2.夏代都城&#xff1a;二里头遗址位于今河南洛阳偃师二里头村。发现了大型绿松石龙形器&#xff0c;被命名为…

死锁的形成

死锁的形成 背景学习资源死锁的本质 背景 面试可能会被问到. 学习资源 一个案例: https://www.bilibili.com/video/BV1pz421Y7kM 死锁的本质 互相持有对方的资源. 存在资源竞争都没有释放. 可能出现死锁. insert into demo_user (no, name) values (6, ‘test1’) on dupl…

MapReduce架构-打包运行

&#xff08;一&#xff09;maven打包 MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff08;例如&#xff1a;jar…

C++发起Https连接请求

需要下载安装openssl //stdafx.h #pragma once #include<iostream> #include <openssl/ssl.h> #include <openssl/err.h> #include <iostream> #include <string>#pragma comment(lib, "libssl.lib") #pragma comment(lib, "lib…

ADI ADRV902x的射频模拟信号输入输出端口的巴伦匹配

根据规格书可知ADRV902x系列的&#xff1a; 【1】输入阻抗是100Ω差分&#xff0c;包括RX端口和ORX端口。 【2】输出阻抗是50Ω差分&#xff0c;包括TX端口。 而射频系统通常采用50Ω的单端走线&#xff0c;所以需要通过正确规格的巴伦完成差分转单端/单端转差分的处理。 巴…

【计算机视觉】OpenCV实战项目:Athlete-Pose-Detection 运动员姿态检测系统:基于OpenCV的实时运动分析技术

运动员姿态检测系统&#xff1a;基于OpenCV的实时运动分析技术 1. 项目概述1.1 技术背景1.2 项目特点 2. 技术架构与算法原理2.1 系统架构2.2 核心算法2.3 模型选择 3. 项目部署与运行指南3.1 环境准备硬件要求软件依赖 3.2 项目配置3.3 运行项目基本运行模式高级参数 4. 常见问…