C# 消息 界面卡顿 界面进程 工作进程

news2024/11/29 12:34:32

一 消息

消息与消息循环,是所有的GUI开发里共同的概念:
消息Message,有的地方也叫事件;
① 鼠标消息;
② 键盘消息;
③ 绘制事件;
④ 窗口最大化、最小化;

1 消息循环

消息循环,Message Loop所有的界面消息,都是一个while循环里处理的用伪代码表示:

List<Message>msgList=new List<Message>()
while(message=GetMessage())
{
   依次处理message..
}

真实的消息循环

Application.Run(new Form1());

具体的消息处理过程:

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
}

所有的界面事件回调,本质上都运行在消息循环里,在消息循环里,作进一步的分发处理。
比如,一个Message是鼠标事件,则分发给相应的空间处理。

void button1_MouseUp(object sender,MouseEventArgs e)
{
}

运行这个消息循环的线程,就是界面线程,在WinForm里,主线程即界面线程。

static void Main()
{
   Application.Run(new Form1());
}

三 界面卡顿

按钮处理程序需要9秒完成;在这个9秒内整个界面是卡主的,不可操作的,为什么?
消息循环:每一个消息处理都要尽快完成

while(message=GetMessage())
{
   switch(消息类型)
      case 鼠标消息;
      case 键盘消息;
}

所有的消息处理回调,都哟啊尽快返回。当处理时间太长时,界面会有卡顿之感(大于300毫秒左右)

四 工作线程

思考:
如果确实需要处理一件耗时较长的工作…
例如,查询数据库,上传下载,编解码…都可能需要较长时间才能完成。怎么解决?

工作线程Work Thread
如果事件处理需要较长时间,应当创建一个线程来处理这个任务。此线程称为“工作线程”。
由于button1_Click()会立即返回,不会引起界面卡顿。

界面线程:一直运行,处理界面事件;
工作线程:工作完成后退出;
回顾线程的特点:独立,并行;
在这里插入图片描述

五 界面的更新

错误的实现:

1 创建工作线程;

2 在工作线程中直接更新TextBox的显示;

观察:运行程序,程序会有崩溃提示。
为什么不能在工作线程中直接访问textBox1呢?
在工作线程中访问UI控件时,需使用Invoke方法

Control.Invoke(method,args)

当调用Invoke时,实际上推送了一个自定义的消息到消息循环中。当消息被处理时,相应的回调被执行。

正确的实现:
① 定义一个委托类型myCallback;
② 定义一个回调处理ShowProgress;
③ 使用Invoke推送一个自定义事件到消息循环;
注意:Invoke消息的回调也是在界面线程中执行的;

第一原则:界面问题的处理不能太久,否则卡顿;
第二原则:当任务时间较长时,则创建工作线程;
第三原则:在工作线程中不可以直接更新UI,需借助Invoke来发送一个自定义的消息;

六 Action与Func

委托,实际上是对一类方法的特征描述;
例如:

public delegate void selfCallback(string str);

表示的是"参数为striing、返回值为void"的方法;

两个通用的Delegate:
System.Action表示返回值为void的方法;
System.Func 表示返回值不是void的方法;
几乎所有的方法,都可以用这两种委托来表示。
例如:

void test1(string a,int b);

由于返回值是void类型,可以用Action表示:

new Action<string,int>(this.test1);

例如:

Student test2(string a,int b)

由于返回值不是void,可以用Func表示

new Func<string,int,Student>(this.test2);

在工作线程里更新UI时,直接使用Action/Func即可,不需要专门定义一个Delegate

this.Invoke(new Action<string>(this.ShowProgress))
public void ShowProgress(string text)
{
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Action与Func
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(new ThreadStart(this.Execute));
            th.Start();
        }

        private void Execute()
        {
            //此回调处理需要3秒才能完成
            this.Invoke(new Action<string>(this.ShowProgress), "3..\r\n");
            Thread.Sleep(1000);

            this.Invoke(new Action<string>(this.ShowProgress), "2..\r\n");
            Thread.Sleep(1000);

            this.Invoke(new Action<string>(this.ShowProgress), "1..\r\n");
            Thread.Sleep(1000);

            this.Invoke(new Action<string>(this.ShowProgress), "OK..\r\n");
        }

        public void ShowProgress(string text)
        {
            //这个方法是在消息循环(界面线程)里
            textBox1.AppendText(text);
        }
    }
}

七 InvokeRequired

Control.InvokeRequired用来判断是不是在工作线程

if(this.InvokeRequired)
{
  //判断当前线程是不是工作线程
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace InvokeRequired
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(new ThreadStart(this.Execute));
            th.Start();
        }

        private void Execute()
        {
            ShowProgress("3\r\n");
            Thread.Sleep(1000);

            ShowProgress("2\r\n");
            Thread.Sleep(1000);

            ShowProgress("1\r\n");
            Thread.Sleep(1000);
            ShowProgress("OK\r\n");
        }
        /// <summary>
        /// 此方法既可以在工作线程中调用、又可以在界面线程中调用
        /// </summary>
        /// <param name="str"></param>
        public void ShowProgress(string str)
        {
            if(this.InvokeRequired)
            {
                //从工作线程中调用
                Console.Write("Call In Work Thread:" + str);
                this.Invoke(new Action<string>(this.ShowProgress), str);
            }
            else
            {
                //从界面线程中调用
                Console.WriteLine("Call in Message Loop:" + str);
                textBox1.AppendText(str);
            }
        }
    }
}

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

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

相关文章

10道不得不会的缓存面试题【缓存】

博主介绍&#xff1a; &#x1f680;自媒体 JavaPub 独立维护人&#xff0c;全网粉丝15w&#xff0c;csdn博客专家、java领域优质创作者&#xff0c;51ctoTOP10博主&#xff0c;知乎/掘金/华为云/阿里云/InfoQ等平台优质作者、专注于 Java、Go 技术领域和副业。&#x1f680; 最…

使用Conda

0. Anaconda Prompt 命令提示符 0.1 验证conda是否被安装 conda --version0.2 conda管理环境 可以用命令复制和删除环境 参考. 1. Conda管理包 1.1 常用包管理功能 查找包查看包安装包 查找分为精确查找和模糊查找&#xff0c;如下图所示 卸载包更新包 1.2 conda管理环…

【实习之velocity】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、图示二、应用场景1.Web应用程序&#xff1a;作为为应用程序的视图&#xff0c;显示数据2.源代码生成&#xff1a;Velocity可用于基于模板生成java源代码3.自…

[c++基础]-vector类

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 目录 一、 vect…

scanf导致程序运行时出现stack smashing

一 栈溢出stack smashing 程序在运行期间破坏了已在操作系统里定义好的栈边界&#xff0c;这种行为具有破坏性&#xff0c;操作系统使用stack smashing detect机制来检测栈溢出。 二 栈溢出简单例子 实例一&#xff1a; #include <stdio.h> #include <stdlib.h>…

基于智能优化算法实现的机械臂避障路径规划(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 针对目前空间机械臂避障路径规划算法计算量大难以达到在线实时规划的缺点,对空间机械臂的在线实时避障路径规划问题进行了研究和…

计算机四级网络-网络技术-第六章 网络管理与网络安全

6.1 网络管理技术 CMIP 采用委托监控机制。 CMIP协议是由IS0组织制定的一种管理协议。管理进程根据事件发生时对网络服务影响的大小来划分事件的严重等级&#xff0c;然后再产生相应的故障处理方案。CMIP的所有功能都要映射到应用层的相关协议上实现。操作和事件报告是通过远…

如何使用腾讯会议录屏?腾讯会议不允许录屏怎么办?这个方法教你解决

​近年来&#xff0c;线上活动越来越活跃&#xff0c;很多人都开始使用腾讯会议进行开会、网课教学等活动。很多人希望使用腾讯会议进行录屏。那么如何使用腾讯会议录屏&#xff1f;腾讯会议不允许录屏怎么办&#xff1f;这个方法教你解决&#xff01; 一、如何使用腾讯会议录屏…

计算机组成原理习题课第三章-5(唐朔飞)

计算机组成原理习题课第三章-5&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

[ElasticSearch]-初识Elastic Stack

[ElasticSearch]-初识Elastic Stack 森格 | 2022年11月 本文是第一次接触Elasticsearch的一些个人总结&#xff0c;介绍了Elastic Stack&#xff0c;如有错误之处&#xff0c;敬请指正。 一、ELK 到 Elastic Stack 注&#xff1a;上图来源于Elasticsearch中文博客 ELK分别是Ela…

PyTorch深度学习笔记之五(使用神经网络拟合数据)

使用神经网络拟合数据 1. 人工神经网络 1.1 神经网络和神经元 神经网络&#xff1a;一种通过简单函数的组合来表示复杂函数的数学实体。 人工神经网络和生理神经网络似乎都使用模糊相似的数学策略来逼近复杂的函数&#xff0c;因为这类策略非常有效。 这些复杂函数的基本构…

多线程轮流打印

一、背景 面试的时候&#xff0c;有一个高频的笔试题&#xff1a; 让2个线程轮流打印&#xff0c;a线程是打印ABCDEFGHIJ&#xff0c;b线程是打印1、2、3、4、5、6、7、8、9、10 二、原理 这种类型的面试题&#xff0c;主要是考察object的wait()方法和notify()方法的使用 …

spring整合Mybatis-P23,24,25

复习Mybatis&#xff08;都是之前的内容&#xff0c;不再解释&#xff09; 6个需要修改或创建的文件 UserMapper package com.Li.mapper;import com.Li.pojo.User;import java.util.List;public interface UserMapper {public List<User> selectUser(); }UserMapper.xm…

如何全面提升架构设计的质量

低成本 低成本本质上是对架构的一种约束&#xff0c;与高性能等架构是冲突的 手段和应用 先设计架构方案&#xff0c;再看如何降低成本 优化 引入缓存虚拟化、容器化性能调优采用高性能硬件采用开源方案 创新 NoSQL vs SQLSQL vs 倒排索引Hadoop vs MySQL 安全性 复杂…

《码出高效:Java开发手册》 四-走进JVM

前言 JVM是java中底层的知识&#xff0c;这里的内容比较复杂&#xff0c;对于一些软件编程&#xff0c;会经常使用&#xff0c;但很多业务其实碰不到这里的知识&#xff0c;下图为目录 介绍 JVM&#xff0c;java虚拟机&#xff0c;它的前身是99年的hotspot java虚拟机&…

vue 计算属性未重新计算 / computed 未触发 / computed 原理源码分析

点击可打开demo 这里在一秒后改了数组里value属性的值 虽然数据有更新&#xff0c;但打开控制台&#xff0c;可以发现computed函数只在初始化时执行了一次 按理说一秒后改变了value值&#xff0c;应该执行两次才对呀&#xff1f; 但如果computed属性这样写&#xff0c;明确写…

数据分析之大数据分析

一 什么是大数据分析 大数据是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。大数据的特点可以概括为5个V&#xff1a;数据量大&…

当湿度达到70蜂鸣器警报

1.编写设备树&#xff0c;添加蜂鸣器等设备 驱动代码&#xff1a; #include <linux/init.h> #include <linux/module.h> #include <linux/i2c.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/device.h> #include …

QCSPCChart for Java R3x0 Crack

Java 的 SPC 控制图工具 版本 3.04 QCSPCChart添加变量控制图&#xff08;X-Bar R、X-Bar Sigma、Individual Range、Median Range、EWMA、MA、MAMR、MAMS 和 CuSum 图&#xff09;、属性控制图&#xff08;p-、np-、c-、u- 和DPMO 图&#xff09;、频率直方图和 Pareto 图到…

[附源码]Python计算机毕业设计Django的旅游景点管理系统的设计与实现

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…