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而言,没法响应 ...
随机推荐
- python--文件操作删除某行
使用continue跳过本次写循环就可以了 #文本内容 Yesterday when I was young 昨日当我年少轻狂 The tasting of life was sweet 生命的滋味是 ...
- 「Python」19个python编写技巧
1. 交换赋值 2. Unpacking 3. 使用操作符in 4. 字符串操作 5. 字典键值列表 6. 字典键值判断 7. 字典 get 和 setdefault 方法 8. 判断真伪 9. 遍历 ...
- Do the Untwist(模拟)
ZOJ Problem Set - 1006 Do the Untwist Time Limit: 2 Seconds Memory Limit: 65536 KB Cryptography ...
- 那些让 Web 开发者们深感意外的事情
作为 Web 开发者,对自己的行业前景,人人都有自己的看法,然而,任何行业都有出人意料的地方.著名的 Web 开发设计博客 Nope.com 曾向他们的读者做了一个调查,请他们列举 Web 开发领域那 ...
- 当月第一天、最后一天、下月第一天,时间date
时间记录,不是时间戳 $thismonth = date('m'); $thisyear = date('Y'); $startDay = $thisyear . '-' . $thismonth . ...
- 【BZOJ 1001】[BJOI2006]狼抓兔子(最大流)
题目链接 最大流裸题,没什么好说吧,恰好点数多,考验网络流的效率,正好练\(Dinic\). #include <cstdio> #include <queue> #inclu ...
- Islands and Bridges(POJ2288+状压dp+Hamilton 回路)
题目链接:http://poj.org/problem?id=2288 题目: 题意:求Hamilton 路径权值的最大值,且求出有多少条权值这么大的Hamilton路径. 思路:状压dp,dp[i] ...
- 【IDEA】IDEA设置新建文件的模板
今天在IDEA中新建JS文件的时候想着也像WebStorm一样可以显示作者和时间,所以就研究了下在IDEA中修改文件创建时的模板. 点击settings找到File and Code Template ...
- hash算法搜索获得api函数地址的实现,"kernel32.dll", "CreateThread"
我们一般要获得一个函数的地址,通常采用的是明文,例如定义一个api函数字符串"MessageBoxA",然后在GetProcAddress函数中一个字节一个字节进行比较.这样弊端很 ...
- ubuntu下中文输入法的配置,建议用fcitx
Fcitx [ˈfaɪtɪks] 是一个支持扩展的输入法框架.它有自己维护的三个输入法,拼音,区位和码表:还支持其他引擎,rime 中州韵,google-pinyin,sunpinyin.Fcitx ...