使用publisher模式控制频繁的UI输出,避免Winform界面假死
http://www.cnblogs.com/Charltsing/p/publisher.html
最近测试task并发任务的效率与线程池的区别,发现了另外一个问题。task建立任务的速度很快,输出到UI的信息过频,导致UI假死。
private void TestMakeTasks(object obj)
{
string msg = ""; //循环创建task
for (int i = 0; i < 3000; i++)
{
//主线程(winform)--子线程(Thread)--工作线程(task)
//不能在循环里面连续访问UI,会造成UI来不及处理,导致假死。
Task<string> tt = Task.Factory.StartNew<string>(test, i);
tt.ContinueWith((t) =>
{
if (t.IsFaulted)
{
string msgexcep = (string.Format("I have observed a {0}", t.Exception.InnerException.GetType().Name));
Interlocked.Increment(ref responsecount);
Interlocked.Decrement(ref threadscount);
}
});
//Thread.Sleep(1); //避免过快发送UI更新请求,导致假死。
msg = " 已发送请求数:" + requestcount.ToString() + " 已完成请求数:" + responsecount.ToString(); //输出线程建立信息给UI,过频会导致假死。
PublishStatus(msg); Interlocked.Increment(ref threadscount);
Interlocked.Increment(ref requestcount);
if (_isStop)
{
PublishMessage("正在退出...\r\n");
break;
}
}
PublishMessage("发送完毕,请等待线程运行完毕!\r\n");
while (responsecount < requestcount)
{
Thread.Sleep(300);
msg = "!已发送请求数:" + requestcount.ToString() + " 已完成请求数:" + responsecount.ToString();
PublishStatus(msg);
}
_isRunning = false;
PublishMessage("\r\n全部线程运行完毕!\r\n");
}
为了解决这个问题,考虑使用publisher模式控制UI输出
public class Publisher
{
public bool isbusy = false; //标志
public delegate void PublishEventHander(object sender, PubEventArgs e); public event PublishEventHander PublishMessage;
public event PublishEventHander PublishStatus; //声明一个可重写的OnPublish的保护函数
protected virtual void OnPublishMessage(PubEventArgs e)
{
if (PublishMessage != null)
{
//Sender = this,也就是Publisher
this.PublishMessage(this, e);
}
}
protected virtual void OnPublishStatus(PubEventArgs e)
{
if (PublishStatus != null)
{
//Sender = this,也就是Publisher
this.PublishStatus(this, e);
}
} /// <summary>
/// 触发publish message事件
/// </summary>
public void IssueMessage(string message)
{
OnPublishMessage(new PubEventArgs(message));
} /// <summary>
/// 触发publish status事件
/// </summary>
public void IssueStatus(string message)
{
if (!isbusy) OnPublishStatus(new PubEventArgs(message)); }
}
同时,在UI输出部分,使用Invoke来阻止更多的UI操作(不能使用BeginInvoke)。
private void WriteStatus(string msg)
{
if (this.lblStatus.InvokeRequired)
{
Invoke(cdWriteStatus, msg);
}
else
{
UpdatelblMethod(msg);
}
}
大致思路是 task创立任务之后,发给publisher一个通知(使用IssueStatus函数),publisher通过OnPublishStatus事件通知给Subscriber,UI界面作为订阅者通过设置publisher的busy状态使得publisher取消后面多余的输出事件。
有问题请联系QQ 564955427
使用publisher模式控制频繁的UI输出,避免Winform界面假死的更多相关文章
- Qt多线程和GUI界面假死(run()是线程的入口,就像main()对于应用程序的作用。分析QThread::exec函数的源码,旧的QMutexLocker模式其实很好用,挡住别人进入抢占资源,可照抄)good
QThread的常见特性: run()是线程的入口,就像main()对于应用程序的作用.QThread中对run()的默认实现调用了exec(),从而创建一个QEventLoop对象,由其处理该线程事 ...
- TIMER门控模式控制PWM输出长度
TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...
- STM32: TIMER门控模式控制PWM输出长度
搞了两天单脉冲没搞定,无意中发现,这个利用主从模式的门控方式来控制一路PWM的输出长度很有效. //TIM2 PWM输出,由TIM4来控制其输出与停止 //frequency_tim2:TIM2 PW ...
- AMQ学习笔记 - 19. 问题解决 - 控制Atomikos的日志输出
概述 在使用Atomikos为ActiveMQ提供JTA支持时,Atomikos在控制台打印了繁琐的日志.这里介绍如何控制Atomikos日志输出的粒度. 解决方案 基于以下三个事实: Atomiko ...
- Client-Side UI Automation Provider - WinForm Sample
Client-Side UI Automation Provider - WinForm Sample 2014-09-15 源代码 目录 引用程序集实现提供程序接口分发客户端提供程序注册和配置客户 ...
- Server-Side UI Automation Provider - WinForm Sample
Server-Side UI Automation Provider - WinForm Sample 2014-09-14 源代码 目录 引用程序集提供程序接口公开服务器端 UI 自动化提供程序从 ...
- 告诉你吧,一套皮肤在winform与wpf开发模式下实现的界面效果同样精彩,winform界面和wpf界面。
一.同一资源: 二.先上软件界面: (1)wpf界面: 在wpf中实现这样类似web风格的软件界面就不用我多说了,在wpf实现这样的风格是很简单的,完全像网页设计一样的. (2)winform界面 在 ...
- C#:控制WinForm界面的显示
控制WinForm界面在屏幕的四个角落显示,具体代码中有说明: using System; using System.Collections.Generic; using System.Drawing ...
- Winform 界面执行耗时操作--UI卡顿假死问题
UI卡顿假死问题 误区1:使用不同的线程操作UI控件和耗时操作(即,跨线程操作UI控件CheckForIllegalCrossThreadCalls = false;), 注意:此处只是为了记录... ...
随机推荐
- 将DataTable中的数据一次性提交到数据库中
实现功能的核心代码 SqlConnection destinationConnection = new SqlConnection(connectionString);destinationConne ...
- xp,windows7,windows8,windows10那个系统好用些
Windows XP:这曾经是微软史上最好的.最受欢迎.最受好评的可以说空前绝后的系统,虽然,XP系统对电脑配置的要求很低,基本现在所有的电脑都支持安装该系统,可它太老旧了,到2014年4-5月份微软 ...
- win10安装nodejs遇到提示错误代码2503怎么办
我们在安装某个软件的时候,最闹心的就是遇到提示安装失败或错误,比如win10系统在安装nodejs遇到提示错误代码2503,遇见这个问题也不要慌张,今天小编就来告诉大家怎么解决这个问题. 1.打开智能 ...
- C语言 统计一串字符中空格键、Tab键、回车键、字母、数字及其他字符的个数(Ctrl+Z终止输入)
//凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ #include<stdio.h> void main(){ , num=, blank=, ...
- Linux常用命令-文本查看篇
前言 Linux常用命令中,除了cat还有很多其他用于文本查看的命令.本文将简单介绍一下这些文本查看的命令. 全文本显示--cat cat可能是常用的一个文本查看命令了,使用方法也很简单: cat f ...
- 删除window10没用的服务
最近学习了下resin,出了个问题,它默认端口是8080,跟Tomcat冲突了,我在使用的时候遇到了个奇怪的事情,resin4.0一直占用着我的8080端口,哪怕我用dos命令把它强制停止,不出五秒钟 ...
- 前端使用node.js+express+mockjs+mysql实现简单服务端,2种方式模拟数据返回
今天,我教大家来搭建一个简单服务端 参考文章: https://www.jianshu.com/p/cb89d9ac635e https://www.cnblogs.com/jj-notes/p/66 ...
- Jenkins+Ansible+Gitlab自动化部署三剑客-gitlab本地搭建
实际操作 准备linux初始环境 关闭防火墙 systemctl stop firewalld 开机自己关闭 systemctl disable firewalld 设置安全配置 为关闭 vim /e ...
- Linux:Day5 shell编程初步、grep
bash的基本特性(3) 1.提供了编程环境 程序编程风格: 过程式:以指令为中心,数据服务于指令: 对象式:以数据为中心,指令服务于数据: shell程序:提供了编程能力,解释执行:过程式.解释执行 ...
- Linux中的cat、more、less、head、tail命令
cat [OPTION]... [FILE]... -E:显示行结束符$ -n:对显示出的每一行进行编号 cat后面可以加多个文件,也就是说可以把多个文件连接起来,然后dump到标准输出. 另外cat ...