c#后台线程更新界面
参考文章《C# 线程更新UI界面》
主窗口
public frmMain()
{
InitializeComponent();
} /// <summary>
/// 主窗口加载事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmMain_Load(object sender, EventArgs e)
{
try
{ //设置默认状态
mc_MachineStatusHander = new Common.MachineStatusHandler();
mc_MachineStatusHander.mc_MachineProduceStatusHandler.UpdateMachineSignalDelegate += UpdateMachineSignalStatus;//后台线程中指定委托为更新界面方法 mc_MachineStatusHander.ChangeStatus("Online", "运行", "WesChen", "001A");
SettingLight(); }
catch (Exception ex)
{
ShowErrorMessage(ex.Message, "系统初始化");
this.Close();
}
}
界面更新主方法
/// <summary>
/// 获取机器信号,并更新界面
/// </summary>
/// <param name="singnal">机器信号</param>
delegate void UpdateMachineProduceSignalDelegate(Common.MachineProduceStatusHandler.SignalType singnal);
private void UpdateMachineSignalStatus(Common.MachineProduceStatusHandler.SignalType signal)
{
if (InvokeRequired)
{
this.Invoke(new UpdateMachineProduceSignalDelegate(delegate (Common.MachineProduceStatusHandler.SignalType s)
{ if (signal.ToString().IndexOf("X01") != -)
{
btn_SignalX01.BackColor= System.Drawing.Color.FromArgb(, , );
btn_SignalX01.ForeColor = System.Drawing.Color.FromArgb(, , );
}
else
{
btn_SignalX01.BackColor = System.Drawing.Color.FromArgb(, , );
btn_SignalX01.ForeColor = System.Drawing.Color.FromArgb(, , );
} lab_ProductCount.Text = "累计生产数量:" + mc_MachineStatusHander.mc_MachineProduceStatusHandler.ProductCount;
lab_LastLifeCycleTime.Text = "最后一次生产用时:" + Common.CommonFunction.FormatMilliseconds(mc_MachineStatusHander.mc_MachineProduceStatusHandler.LastProductUseMilliseconds); }), signal);
}
else
{
if (signal.ToString().IndexOf("X01") != -)
{
btn_SignalX01.BackColor = System.Drawing.Color.FromArgb(, , );
btn_SignalX01.ForeColor = System.Drawing.Color.FromArgb(, , );
}
else
{
btn_SignalX01.BackColor = System.Drawing.Color.FromArgb(, , );
btn_SignalX01.ForeColor = System.Drawing.Color.FromArgb(, , );
} lab_ProductCount.Text = "累计生产数量:" + mc_MachineStatusHander.mc_MachineProduceStatusHandler.ProductCount;
lab_LastLifeCycleTime.Text = "最后一次生产用时:" + Common.CommonFunction.FormatMilliseconds(mc_MachineStatusHander.mc_MachineProduceStatusHandler.LastProductUseMilliseconds); }
}
后台线程
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Text.RegularExpressions;
using System.Diagnostics; namespace MES_MonitoringClient.Common
{
/// <summary>
/// 机器生产状态
/// </summary>
public class MachineProduceStatusHandler
{ /// <summary>
/// 信号类型
/// </summary>
public enum SignalType
{
Unknow, X01,
X02,
X03, X01_X02,
X01_X03, X02_X03, X01_X02_X03
} /// <summary>
/// 回复信号前缀
/// </summary>
private static string singnalDefaultStart = Common.ConfigFileHandler.GetAppConfig("GetSerialPortDataDefaultSignal_StartPrefix");
/// <summary>
/// 回复信号后缀
/// </summary>
private static string singnalDefaultEnd = Common.ConfigFileHandler.GetAppConfig("GetSerialPortDataDefaultSignal_EndPrefix"); /*-------------------------------------------------------------------------------------*/ /// <summary>
/// 产品生命周期(计算时间)
/// </summary>
//private List<MachineProcedure> _MachineProcedureListForTime=null; /// <summary>
/// 产品生命周期(计算次数)
/// </summary>
private List<MachineProcedure> _MachineProcedureListForCount=null; /// <summary>
/// 产品周期计数(生产数量)
/// </summary>
public int ProductCount = ; /// <summary>
/// 空产品周期计数(不完整[空啤]生产数量)
/// </summary>
public int ProductErrorCount = ; /// <summary>
/// 单次产品周期秒数
/// </summary>
public long LastProductUseMilliseconds = ; /// <summary>
///
/// </summary>
public Nullable<DateTime> LastX03SignalGetTime = null; /// <summary>
/// 上一个信号
/// </summary>
public SignalType LastSignal; /// <summary>
/// 更新机器信号后更新界面的方法与委托
/// </summary>
/// <param name="signalType"></param>
public delegate void UpdateMachineSignal(SignalType signalType);
public UpdateMachineSignal UpdateMachineSignalDelegate; /*-------------------------------------------------------------------------------------*/ /// <summary>
/// 构造函数,处理初始化的参数
/// </summary>
public MachineProduceStatusHandler()
{
//产品生命周期(计算时间)
//_MachineProcedureListForTime = new List<MachineProcedure>(); //产品生命周期(计算次数)
_MachineProcedureListForCount = new List<MachineProcedure>();
} /*-------------------------------------------------------------------------------------*/ /// <summary>
/// 更新信号方法
/// </summary>
/// <param name="newSingnal">新信号</param>
public void ChangeSignal(string newSingnal)
{
string convertSingnalString = ConvertSingnalString(newSingnal); //判断是正常的信号
if (!string.IsNullOrEmpty(convertSingnalString))
{
//判断X信号
SignalType convertSingnalStatusType = ConvertSingnalStatus(convertSingnalString); if (convertSingnalStatusType != LastSignal)
{ #region 与上一次信号不同 if (convertSingnalStatusType == SignalType.X03)
{
#region 自动信号(区分上一个信号) _MachineProcedureListForCount.Add(new MachineProcedure()
{
ProcedureID = convertSingnalString,
ProcedureCode = convertSingnalStatusType.ToString(),
ProcedureName = "自动",
}); if (LastSignal == SignalType.X01_X03)
{
//结束产品周期并计时
if (LastX03SignalGetTime.HasValue)
{
LastProductUseMilliseconds = (System.DateTime.Now - LastX03SignalGetTime.Value).Milliseconds;
}
LastX03SignalGetTime = System.DateTime.Now;
}
else if (LastSignal == SignalType.X02_X03)
{
//必须包含完整的生命周期才计数
if (CheckHaveRealProduceProcess(_MachineProcedureListForCount))
{
//计数
ProductCount++; _MachineProcedureListForCount.Clear();
_MachineProcedureListForCount.Add(new MachineProcedure()
{
ProcedureID = convertSingnalString,
ProcedureCode = convertSingnalStatusType.ToString(),
ProcedureName = "自动",
});
}
} #endregion
}
else if (convertSingnalStatusType == SignalType.X01_X03 || convertSingnalStatusType == SignalType.X02_X03)
{
#region 开模完成==射胶完成(不区分上一个信号)
//产品生命周期(计算数量)
if (_MachineProcedureListForCount != null && _MachineProcedureListForCount.Count > )
{
//信号
string procedureNameString = string.Empty;
if (convertSingnalStatusType == SignalType.X01_X03) procedureNameString = "开模完成";
else if (convertSingnalStatusType == SignalType.X02_X03) procedureNameString = "自动射胶"; _MachineProcedureListForCount.Add(new MachineProcedure()
{
ProcedureID = convertSingnalString,
ProcedureCode = convertSingnalStatusType.ToString(),
ProcedureName = procedureNameString,
});
} #endregion
} #endregion //上一个信号
LastSignal = convertSingnalStatusType; //根据信号更新界面
UpdateMachineSignalDelegate(LastSignal);
}
}
} /// <summary>
/// 匹配信号是否正常
/// 并返回信号中的模式数字
/// </summary>
/// <param name="inputSingnal">原信号</param>
/// <returns></returns>
private string ConvertSingnalString(string inputSingnal)
{
Regex regex = new Regex("^" + singnalDefaultStart + "[a-fA-F0-9]{4}" + singnalDefaultEnd + "$");
Match match = regex.Match(inputSingnal); if (match.Success)
{
Regex regexMiddle = new Regex("(?<=(" + singnalDefaultStart + "))[.\\s\\S]*?(?=(" + singnalDefaultEnd + "))", RegexOptions.Multiline | RegexOptions.Singleline);
Match matchMiddle = regexMiddle.Match(inputSingnal); return matchMiddle.Value;
}
else
{
return null;
}
} /// <summary>
/// 模式数字转换为X[]信号
/// </summary>
/// <param name="inputSingnal">模式数字[0800,0400,0200,0C00,0A00,0600,0E00等模式数字]</param>
/// <returns></returns>
private SignalType ConvertSingnalStatus(string inputSingnal)
{
if (inputSingnal == "") return SignalType.X01; //开模终止信号
else if (inputSingnal == "") return SignalType.X02;//射胶信号
else if (inputSingnal == "") return SignalType.X03;//自动运行模式信号 else if (inputSingnal == "0C00") return SignalType.X01_X02;
else if (inputSingnal == "0A00") return SignalType.X01_X03;
else if (inputSingnal == "") return SignalType.X02_X03; else if (inputSingnal == "0E00") return SignalType.X01_X02_X03; else return SignalType.Unknow;
} /// <summary>
/// 判断是否是真实的生产流程
/// </summary>
/// <param name="oldMachineProcedureList"></param>
/// <returns></returns>
private bool CheckHaveRealProduceProcess(List<MachineProcedure> oldMachineProcedureList)
{
bool resultFlag = false; bool isX01_X03 = false;
bool isX02_X03 = false;
bool isX03 = false; //判断是否有完整的信号
foreach (var processItem in oldMachineProcedureList)
{
if (processItem.ProcedureCode == SignalType.X01_X03.ToString()) isX01_X03 = true;
if (processItem.ProcedureCode == SignalType.X02_X03.ToString()) isX02_X03 = true;
if (processItem.ProcedureCode == SignalType.X03.ToString()) isX03 = true;
} //完整的信号则算正常生产流程
if (isX01_X03 && isX02_X03 && isX03) resultFlag = true; return resultFlag;
}
}
}
以上方法是可以正常从类内部更新winform界面的
c#后台线程更新界面的更多相关文章
- C# 后台线程更新UI控件
/********************************************************************************* * C# 后台线程更新UI控件 * ...
- 一种WPF在后台线程更新UI界面的简便方法
WPF框架规定只有UI线程(主线程)可以更新界面,所有其他后台线程无法直接更新界面.幸好,WPF提供的SynchronizationContext类以及C#的Lambda表达式提供了一种方便的解决方法 ...
- WPF后台线程更新UI
0.讲点废话 最近在做一个文件搜索的小软件,当文件多时,界面会出现假死的状况,于是乎想到另外开一个后台线程,更新界面上的ListView,但是却出现我下面的问题. 1.后台线程问题 2年前写过一个软件 ...
- 非UI线程更新界面
package com.caterSys.Thread; import java.text.SimpleDateFormat; import java.util.Date; import org.ec ...
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...
- Android异步处理系列文章四篇之一使用Thread+Handler实现非UI线程更新UI界面
目录: Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+L ...
- C# 跨线程更新UI界面的适当的处理方式,友好的退出界面的机制探索
本文主要讲讲C#窗体的程序中一个经常遇到的情况,就是在退出窗体的时候的,发生了退出的异常. 工业软件技术交流群:群1:592132877(满) 群2:948305931 欢迎技术探讨 我们先 ...
- C# Winform 窗体界面”假死”后台线程阻塞 解决办法–BeginInvoke
原文:C# Winform 窗体界面"假死"后台线程阻塞 解决办法–BeginInvoke 这个方法可以用在任何后台任务耗时较长,造成界面“假死”界面控件不更新的情况. 比如要要执 ...
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
随机推荐
- IOS性能调优系列:使用Time Profiler发现性能瓶颈
硬广:<IOS性能调优系列>第五篇,预计会有二十多篇,持续更新,欢迎关注. 之前四篇都是关注于内存方面,分析了内存泄漏.僵尸对象.内存分配,本篇介绍Time Profiler工具的使用,开 ...
- [大数据可视化]-saiku的源码包Bulid常见问题和jar包
最近在做kylin+mondrian+saiku的二次开发的时候,Bulid saiku的源码出现了很多问题,基本上一大部分问题jar找不到问题,很多jar国内网站都找不到.这时候只有手动下载然后注册 ...
- 目前最快速的多线程Kmeans算法,java实现
目前最快速Kmeans算法,并由java实现!面对很大的K值表现依然很好. 代码地址: https://github.com/Jethu1/fastKmeans #1.这是一个由java实现的的,多线 ...
- [NOIP2003]栈 题解(卡特兰数)
[NOIP2003]栈 Description 宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n(图示为1到3的情况),栈A的深度大于n. 现在可以进行两种操作: 1.将一个数,从操作数序 ...
- css各种姿势的水平居中
首先是最常用的,利用margin属性的auto来进行水平居中 margin: 0 auto; 其中0是指上下的margin,auto是左右的margin,margin这个属性的简写是按顺时针走的,也就 ...
- 利用media query写响应式布局
最近才接触到响应式布局的概念,之前用到的bootstrap就是一种响应式布局的框架.学习的时候参考了http://blog.csdn.net/shoyer/article/details/829301 ...
- NYOJ 117 求逆序数 (树状数组)
题目链接 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出 ...
- Verilog笔记.2.数字逻辑电路
1.数字逻辑电路的种类:1) 组合逻辑:输出只是当前输入逻辑电平的函数(有延时),与电路的原始状态无关的逻辑电路.也就是说,当输入信号中的任何一个发生变化时,输出都有可能会根据其变化而变化,但与电路目 ...
- keypress 、keydown、keyup后触发回车
1.keypress .keydown.keyup的区别 keypress表示键盘按下的全过程,只有按下任意字母数字键(后退.删除等系统功能键无效)时才触发,捕获到的keyCode区分大小写 keyd ...
- 五. Jmeter--HTTP Cookie Manager
1. 添加HTTP Cookie Manager 2.添加登录login http,request info 和 HTTP Header Manager 中的信息是从fiddler中拿的, 至于hea ...