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而言,没法响应 ...
随机推荐
- 学习 C++的用途,(前辈总结)
C++准确说是一门中级语言,介于汇编和高级语言之间吧,要求程序员了解计算机的内部数据存储.个人认为,作为学生还是花功夫学C++,因为<设计模式><数据结构>这些课程基本上还是C ...
- Ping命令网络监测
按照由近到远原则: 1. ping 127.0.0.1 先检查TCP/IP协议栈是否正常. 2. ping 本地ip 检查网卡是否工作正常. 3. ping 网关地址 检查和网关连接性. 4. pin ...
- 【BZOJ】1297: [SCOI2009]迷路
[题意]给定n个点的有向带边权图,求0到n-1长度恰好为T的路径数.n<=10,T<=10^9,边权1<=wi<=9. [算法]矩阵快速幂 [题解]这道题的边权全部为1时,有简 ...
- jQuery.Event的一些用法
直接写用法 //创建一个事件 var event = $.Event("事件类型",["定义的事件参数最终将出现在e1中"]); //绑定一个处理器 $(obj ...
- 45、如何使用python删除一个文件?
若想利用python删除windows里的文件,这里需要使用os模块!那接下来就看看利用os模块是如何删除文件的! 具体实现方法如下! os.remove(path) 删除文件 path. 如果pat ...
- Django之动态验证码的生成
kind.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- sqlmap的使用方法 ——时光凉春衫薄
普通注入 Sqlmap -u “http://www.xxxxxx.com/xxxx/xxx/xxx.xxx?xx=xx” --dbs 找到一个sql的注入点 探测他的库名 access的直接探表 ...
- 关于linux系统如何实现fork的研究(一)【转】
转自:http://www.aichengxu.com/linux/4157180.htm 引言 fork函数是用于在linux系统中创建进程所使用,而最近看了看一个fork()调用是怎么从应用到gl ...
- oracle中的符号含义
1.Oracle数据库存储过程中:=是什么意思?答:赋值的意思.举例:str := 'abcd';将字符串abcd赋值给变量str. 2.oracle 存储过程中的 := 和=有什么区别?答::= 是 ...
- 你需要知道的Nginx配置二三事
做服务端开发的,工作中难免会遇到处理Nginx配置相关问题.在配置Nginx时,我一直本着“照葫芦画瓢”的原则,复制已有的配置代码,自己修修改改然后完成配置需求,当有人问起Nginx相关问题时,其实仍 ...