WinForm——软件加载读条界面卡死问题

news2024/12/22 16:55:14

WinForm——软件加载读条界面卡死问题

  • 前言
  • 一、问题现象
  • 二、测试部分代码
    • 1.Loading窗体
    • 2.加载代码Program处
  • 三、分析原因
  • 四、解决方案代码
    • 1.Loading窗体
    • 2.加载代码Program处


前言

在制作软件开启界面,读条加载时,在Program中new了个Loading窗体,却发现窗体显示但是界面中的控件显示却不跟随改变,甚至出现卡死的情况,故分析产生的原因,并找到解决方案。


一、问题现象

正常情况:
在这里插入图片描述

状况一:(通过Form中自己写的Set去设置文本的)
在这里插入图片描述
状况二:(通过Form定时器自动循环去写文本的)
在这里插入图片描述
状况三:(通过Form中自定义线程循环去写文本的)
在这里插入图片描述

二、测试部分代码

1.Loading窗体

代码如下:

        public FrmLoading()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
        }


        public void SetPercentVal(int val,string message)
        {
            this.Invoke(new Action(() =>
            {
                this.SuspendLayout();
                pgb_1.Value = val;
                //lb_Percent.Text = "%" + pgb_1.Value;
                //lb_Message.Text = message;
                this.ResumeLayout();
            }));
        }

        private void FrmLoading_Load(object sender, EventArgs e)
        {
            Thread thread = new Thread(a);
            thread.IsBackground = true;
            thread.Start();

            //this.DoubleBuffered = true;
            timer1.Enabled = true;
        }

        void a() 
        {
            while (true)
            {
                this.Invoke(new Action(() =>
                {
                    lb_Percent.Text = "%" + pgb_1.Value;

                }));

            }
            //lb_Message.Text = Meaagae;

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //if (pgb_1.Value == 100)
            //{
            //    if (this.InvokeRequired)
            //    {
            //        this.Invoke((Action)this.Close);
            //    }
            //    else
            //    {
            //        this.Close();
            //    }
            //}
            //else
            //{
            //    lb_Percent.Text = "%" + pgb_1.Value;
            //    //lb_Message.Text = Meaagae;
            //}
        }

2.加载代码Program处

代码如下:

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            LogHelper.WriteInfo("------------------------------------------------");
            LogHelper.WriteInfo("软件启动。");
            LogHelper.WriteInfo("------------------------------------------------");

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            
            Global_Value.G_LoadingFrm = new UI_Frm.FrmLoading();
            Global_Value.G_LoadingFrm.Show();

            while (Global_Value.G_LoadingFrm == null || !Global_Value.G_LoadingFrm.Visible)
            {
                System.Threading.Thread.Sleep(100);
            }

            //初始化
            Global_Method.Ini();

            Global_Value.G_LoadingFrm.SetPercentVal(90, "初始化界面");

            Global_Value.G_MainFrm = new FrmMain();
            Global_Value.G_MainFrm.Visible = true;

            Global_Value.G_LoadingFrm.SetPercentVal(100, "加载完成");
			Global_Value.G_LoadingFrm.Close();
			
            Application.Run(Global_Value.G_MainFrm);
        }


三、分析原因

以Timer版本的举例,在 C# 的 Windows 窗体应用程序中,Timer 组件的 Tick 事件会在 UI 线程上触发。这意味着,当调用 Application.Run 方法启动主消息循环后,UI 线程开始处理窗体和控件的消息,并触发 Timer 组件的 Tick 事件。
如果在 Program 类中的 Main 方法中先创建窗体并启动定时器,然后再调用 Application.Run,由于主消息循环尚未开始,UI 线程不会触发 Tick 事件,因此事件处理程序不会执行。
其他两种情况也都相类似,也都是未启用消息循环导致,文本不跟新卡死的情况。故有如下的解决方案。

四、解决方案代码

再Loading界面开始时就开启消息循环,并在其结束后关闭。
具体优化代码(部分)如下:

1.Loading窗体

代码如下:

    public partial class FrmLoading : Form
    {
        public FrmLoading()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
        }


        public void SetPercentVal(int val,string message)
        {
            this.Invoke(new Action(() =>
            {
                pgb_1.Value = val;
                lb_Percent.Text = "%" + pgb_1.Value;
                lb_Message.Text = message;
            }));
        }

        private void FrmLoading_Load(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            if (pgb_1.Value == 100)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke((Action)this.Close);
                }
                else
                {
                    this.Close();
                }
            }
        }
    }

2.加载代码Program处

代码如下:

        static void Main()
        {
            LogHelper.WriteInfo("------------------------------------------------");
            LogHelper.WriteInfo("软件启动。");
            LogHelper.WriteInfo("------------------------------------------------");

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            var loadingFormThread = new System.Threading.Thread(ShowLoadingForm); // 创建加载界面线程
            loadingFormThread.Start(); // 启动加载界面线程

            while (Global_Value.G_LoadingFrm == null || !Global_Value.G_LoadingFrm.Visible)
            {
                System.Threading.Thread.Sleep(100);
            }

            //初始化
            Global_Method.Ini();


            Global_Value.G_LoadingFrm.SetPercentVal(90, "初始化界面");

            Global_Value.G_MainFrm = new FrmMain();
            Global_Value.G_MainFrm.Visible = true;

            Global_Value.G_LoadingFrm.SetPercentVal(100, "加载完成");

            loadingFormThread.Join();//等待加载界面结束
            Application.Run(Global_Value.G_MainFrm);
        }

        private static void ShowLoadingForm()
        {
            Global_Value.G_LoadingFrm = new UI_Frm.FrmLoading();
            Application.Run(Global_Value.G_LoadingFrm);
        }
    }

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

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

相关文章

02 表达客观事物的术语

文章目录 02 表达客观事物的术语类与对象&#xff08;1&#xff09;定义与表示&#xff08;2&#xff09;类名(类的标识)&#xff08;3&#xff09;属性(attribute)属性的作用范围&#xff1a;定义属性的格式为&#xff1a; (4)操作(operation)表达操作的完整语法格式 &#xf…

帮忙投票的链接创建投票链接设置投票怎么弄的微信怎么

近些年来&#xff0c;第三方的微信投票制作平台如雨后春笋般络绎不绝。随着手机的互联网的发展及微信开放平台各项基于手机能力的开放&#xff0c;更多人选择微信投票小程序平台&#xff0c;因为它有非常大的优势。 1.它比起微信公众号自带的投票系统、传统的H5投票系统有可以图…

【CMake 入门与进阶(7)】 CMakeLists.txt 部分常用变量-续(附使用代码)

继续来学习CMakeLists.txt 常用变量 描述系统的变量 顾名思义&#xff0c;这些变量描述了系统相关的一些信息&#xff1a; 变量说明CMAKE_HOST_SYSTEM_NAME运行 cmake 的操作系统的名称&#xff08;其实就是 uname -s&#xff09;CMAKE_HOST_SYSTEM_PROCESSOR运行 cmake 的操…

Android协程

协程 文章目录 协程1.讲协程之前的一些相关概念1.并发与并行2.同步与异步3.阻塞3.1Looper的阻塞3.1.1 loop的源码3.1.2loopOnce源码3.1.3注意 3.2Looper处于死循环是否会导致ANR3.2.1ANR是什么3.2.2Looper的死循环是否会导致ANR3.2.3总结 4.挂起4.1阻塞和挂起的区别 5.多任务 2…

pytorch深度学习框架—torch.nn模块(二)

pytorch深度学习框架—torch.nn模块&#xff08;二&#xff09; 激活函数 pytorch中提供了十几种激活函数&#xff0c;常见的激活函数通常为S形激活函数&#xff08;Sigmoid&#xff09;双曲正切激活函数(Tanh) 和线性修正单元&#xff08;ReLu&#xff09;激活函数等 层对应的…

Material—— RBD(Houdini To UE)

Houdini刚体碎块导入UE&#xff0c;有两个方面需还原&#xff0c;一是材质还原&#xff0c;一是动态还原&#xff1b; 一&#xff0c;ABC to UE 材质方面&#xff0c;Houdini里的每个Primtive Group属性&#xff0c;都表示UE内的对应材质球&#xff1b;导入时勾选Find Material…

AST使用(一)

关于安装及环境配置可以看https://mp.csdn.net/mp_blog/creation/editor/131155968 下面所有案例的JS原代码如下&#xff1a; const a 3; let string "hello"; for (let i 0;i < 3;i){string "world" } console.log("string",string) …

深度学习QA之卷积神经网络

深度学习Q&A之卷积神经网络 前言1 卷积基础知识问题1 简述卷积的基本操作&#xff0c;并分析其与全连接层的区别 &#xff08;难度&#xff1a; ★ \bigstar ★&#xff09;分析与解答&#xff1a; ♣ \clubsuit ♣ 局部连接: ♣ \clubsuit ♣ 权值共享: ♣ \clubsuit ♣ 输…

ubuntu 20.04 aarch64 平台交叉编译 opencv

编译环境 win10 64 位 VMware Workstation Pro 16 虚拟机 虚拟机安装 ubuntu 20.04 opencv 版本&#xff1a; 来自 github 当前最新 4.7 目的 交叉编译 opencv&#xff0c;用于 嵌入式 aarch64 平台 下载 opencv 可以直接从 github 下载 release 版本或者 使用 git clon…

『2023北京智源大会』6月9日上午|开幕式及全体大会

『2023北京智源大会』6月9日上午|开幕式及全体大会 文章目录 一. 黄铁军丨智源研究院院长1. 大语言模型2. 大语言模型评测体系FlagEval3. 大语言模型生态(软硬件)4. 三大路线通向 AGI(另外2条路径) 二. Towards Machines that can Learn, Reason, and Plan(杨立昆丨图灵奖得主…

Spring Boot整合JPA

文章目录 一、Spring Boot整合JPA&#xff08;一&#xff09;创建Spring Boot项目JPADemo&#xff08;二&#xff09;创建ORM实体类1、创建评论实体类 - Comment2、创建文章实体类 - Article &#xff08;三&#xff09;创建自定义JpaRepository接口 - ArticleRepository&#…

【Flutter】Flutter 中处理 loading 状态

文章目录 一、引言二、在 Flutter 中处理 loading 状态三、用具体业务逻辑代码示例展示四、常见问题及解决方案五、结语 一、引言 今天我们将一起探讨在 Flutter 中如何控制 loading 状态。 Flutter&#xff0c;作为一个高效、简洁的 UI 框架&#xff0c;已经在全球范围内得到…

FPGA基础知识-数据流建模

目录 学习目标 学习内容 1.门的类型 2.门延迟 学习时间 学习小结 学习目标 学习Verilog 提供的门级原语 理解门的实例引用、门的符号以及andor&#xff0c;bufnot类型的门的真值表 学习如何根据电路的逻辑图来生成verilog描述 讲述门级设计中的上升、下降和关断延迟 …

【MyBatis学习】MyBatis操纵数据库进行查询操作 ?MyBatis与JDBC想比怎么样,赶快与我一起探索吧 ! ! !

前言: 大家好,我是良辰丫,从今天开始我们就要进入MyBatis的学习了,请君与我一起操纵数据库,MyBatis到底是什么呢?我们慢慢往下瞧! ! !&#x1f48c;&#x1f48c;&#x1f48c; &#x1f9d1;个人主页&#xff1a;良辰针不戳 &#x1f4d6;所属专栏&#xff1a;javaEE进阶篇之…

前端——自定义组件

目录 一、创作纪念日——6月7日&#xff08;机缘巧合&#xff09; 二、收获 三、前端组件 3.1、重要的CSS 3.2、实用组件 1、站点访问次数 2、鼠标样式 3、烟花点击特效 4、GIF动态小人&#xff08;出现在左下角&#xff09; 5、天气插件 6、音乐播放器 3.3、CSS组…

leetcode337. 打家劫舍 III(java)

打家劫舍 leetcode337. 打家劫舍 III题目描述 暴力递归解题思路代码演示 递归加缓存代码演示 动态规划专题 leetcode337. 打家劫舍 III 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/house-robber-iii 题目描述 小偷又…

湖南大学CS-2019期末考试解析

【特别注意】 答案来源于@wolf 是我在备考时自己做的,仅供参考,若有不同的地方欢迎讨论。 【试卷评析】 有必要一做。 【试卷与答案】 一. 填空题(10 分,每空 2 分) 1. 0xb1e56f07 存放在采用小端存储的机器上,地址为 0x3287 到 0x328a ,则 0x3288 处存…

远程仓库拉不下来怎么办

因为项目需要做一个word转pdf的功能, 当我想要从阿里的仓库引入依赖时发现版本一直报错,无论怎么引入都爆红😭😭 *我将aspose的包先下载到本地,然后再安装安装到本地的maven仓库* mvn install:install-file -Dfile=C:\Users\Administrator\Downloads\aspose-words-18.…

Day01 项目简介分布式基础概念 -谷粒商城

最近在改进公司开发的商城项目&#xff0c;看到了尚硅谷的谷粒商城&#xff0c;就快速学习了下&#xff0c;因为之前的Kafka,Redis都是在这学习的&#xff0c;还有大数据的Flink。所以感觉一定不错&#xff0c;就开始了。 这里做一下学习笔记 一、项目简介 1 、项目背景 1 &…

一文看懂分布式存储 Ceph 架构原理

【摘要】本文带你层层深入Ceph的架构原理、读写原理&#xff0c;从而理解Ceph的特性及其应用场景。 1. 什么是Ceph&#xff1f; 首先&#xff0c;我们从 Ceph的官方网站上&#xff0c;可以看到&#xff1a;“Ceph is a unified, distributed storage system designed for exc…