java invoke假死_多线程、委托、Invoke解决winform界面卡死的问题,并带开关

一、知识点介绍

1,更新控件的内容,应该调用控件的Invoke方法。

Invoke指: 在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。该方法接收一个委托类型和委托的参数,因此需要定义委托类型变量,然后传递给Invoke方法。

如果其他线程直接调用方法更新控件内容,报错:线程间操作无效: 从不是创建控件“richTextBox1”的线程访问它。

2,委托的本质是某一类型的方法,这些方法具有相同的参数和返回类型。

委托类似于C语言中的函数指针,可以指向多个相同类型的函数。

定义委托,只需要在函数返回类型前加上delegate关键词,把函数体大括号{}的内容换成分号即可。比如:

public delegate void DelegateFun(string msg);

DelegateFun就代表了一个函数类型,它接收string参数,返回void。

3,开辟一个线程,直接启动,后面通过挂起和唤醒实现暂停功能。

Thread t = new Thread(Run);

t.Start(); // 启动

通过判断线程状态,决定是否唤醒线程。

if (t.ThreadState == ThreadState.Suspended) // 如果被挂起了,就唤醒

{

t.Resume();

}

暂停就挂起线程:

t.Suspend(); // 停止,挂起线程

注:也可以定义一个开关,用来控制开始和结束,在开关为false的时候,直接continue,这样表现为暂停输出,但是实际上线程一直在运行。

二、界面和代码

5de8566c9f95832be712e225280d4cfd.png

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Threading;

namespace WindowsFormsApplication3

{

public partial class Form2 : Form

{

public Form2()

{

InitializeComponent();

}

///

/// 因为控件的Invoke方法需要接收委托变量,因此需要定义委托和委托变量

/// 定义一个委托,接收一个参数

///

///

public delegate void DelegateFun(string msg);

///

/// 定义一个委托变量

/// 这个委托变量,需要初始化指定具体的方法;然后传递给控件的Invoke方法调用。

///

public DelegateFun Fun1;

///

/// 定义一个线程,处理数据,并更新界面

///

private Thread t = null;

// 开始按钮

private void button1_Click(object sender, EventArgs e)

{

this.Invoke(Fun1, "开始...");

// 增加判断,避免每次单击都开辟一个线程

if (t == null)

{

t = new Thread(Run);

t.Start();

}

if (t.ThreadState == ThreadState.Suspended) // 如果被挂起了,就唤醒

{

t.Resume();

}

}

// 结束执行

private void button2_Click(object sender, EventArgs e)

{

t.Suspend(); // 停止,挂起线程

this.Invoke(Fun1, "...停止");

}

// 具体做事情的方法

public void Run()

{

//...... 处理一些事情,然后输出日志

int i = ;

while (true)

{

i++;

// this指Form2

//Invoke指: 在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。

//Invoke的参数是一个委托类型,因此必须定义委托变量

this.Invoke(Fun1, i.ToString());

}

}

//在form初始化的时候,给委托变量赋值具体的方法

private void Form2_Load(object sender, EventArgs e)

{

//给委托变量初始化具体的执行方法

Fun1 = Print;

}

// 输出日志的方法

public void Print(string msg)

{

// 新开辟的线程,不能直接调用这个方法。原因是控件只能由创建它的线程调用。

// 其他线程调用提示错误: 线程间操作无效: 从不是创建控件“richTextBox1”的线程访问它。

this.richTextBox1.AppendText(msg + "\r\n");

this.richTextBox1.ScrollToCaret();

}

}

}

三、参考文章

1, C#多线程解决界面卡死问题的完美解决方案,BeginInvoke而不是委托delegate

双缓冲队列解决WPF界面卡死

工作中的项目,CS客户端会通过MQ接收前端设备发送的信息,之前测试的时候,由于测试的数据不大,没有进行压力测试,软件可以正常工作,随着项目现场设备数量的增加,CS客户端从MQ中订阅的数据量不断增加,最 ...

使用multiprocessing解决PyMuPDF不支持多线程加载导致的界面卡死无响应问题,及一个PyQt5实现的简易PDF阅读器例子

最近在用PyMuPDF实现一个PDF阅读器,发现PyMuPDF在加载某些epub时耗时非常长,有的长达10几秒,会导致界面卡死无响应. 尝试用多线程后台加载,发现还是不能解决问题,和作者交流(issu ...

Centos7解决图形界面卡死问题

经常会遇到图形界面卡死,搜了一搜,解决办法如下: killall -9 gnome-shell

【C#】多线程解决UI界面卡死的问题

一个经典的例子: http://www.cnblogs.com/wangchuang/p/4485797.html 问题: 都说Invoke是同步的,BeginInvoke是异步的,但为何用Begin ...

解决 winform 界面对不齐 z

一个winform的程序,本机上界面对得很齐,到一到客户的机器上就惨不忍睹,一番研究后搞定: 1. AutoScaleMode = None 2. BackgroundImageLayout = No ...

解决 winform 界面对不齐

最近做了一个winform的程序,本机上界面对得很齐,到一到客户的机器上就惨不忍睹,一番研究后搞定: 1. AutoScaleMode = None 2. BackgroundImageLayout ...

解决WinForm界面闪烁问题

前言 之前將.net 1.1 Windows Form程式升級到.net 4.0,結果在開畫面時,閃的非常利害!  於是就開始找解決方法. 研究及解決 開始找到了設定DoubleBuffer=true ...

C#多线程解决界面卡死问题的完美解决方案,BeginInvoke而不是委托delegate 转载

问题描述:当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决一个主线程来创建界面,使用一个子线程来执行程 ...

WinForm多线程+委托防止界面卡死

1.当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决 using System; using System.Collections.Gener ...

随机推荐

【转载】写一个js库需要怎样的知识储备和技术程度?

作者:小爝链接:https://www.zhihu.com/question/30274750/answer/118846177来源:知乎著作权归作者所有,转载请联系作者获得授权. 1,如何编写健壮的 ...

jquery-ui-处理拖动位置Droppable,Draggable

一.效果.如下图中,各途中可相互拖拉,右下角可删除.注意图1和图2对比区别 图1 图2 二.源码详解 html源码

c++模板类

c++模板类 理解编译器的编译模板过程 如何组织编写模板程序 前言常遇到询问使用模板到底是否容易的问题,我的回答是:“模板的使用是容易的,但组织编写却不容易”.看看我们几乎每天都能遇到的模板类吧,如S ...

Unity3D绑定button监听事件

一.可视化创建及事件绑定 第一步:通过Hierarchy面板创建button,如图 第二步:创建一个脚本名为TestClick,并定义一个名为Click的public方法 ? 1 2 3 4 5 6 ...

Ubuntu 14.04下安装Hadoop2.4.0 (单机模式)

转自 http://www.linuxidc.com/Linux/2015-01/112370.htm 一.在Ubuntu下创建Hadoop组和hadoop用户 增加hadoop用户组,同时在该组里增 ...

poj---(2886)Who Gets the Most Candies?(线段树+数论)

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 10373   Acc ...

tornado介绍

一.定义 tornado是一个异步非阻塞模型的服务器(tcp/http).web框架. 二.特性 1.高并发 原因:其一,网络事件循环部分根据操作系统选择最高效的,如Linux会是epoll: 其二, ...

九度OJ 1511 从尾到头打印链表

题目地址:http://ac.jobdu.com/problem.php?pid=1511 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例. 每一组测 ...

使用APPLICATION制作缓存,转存一下,有一段写的还可以。

public sealed class CacheManager   {   private HttpApplicationState appPool = null;   ///

MySQL--连接属性

The capability flags are used by the client and server to indicate which features they support and w ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值