参考文章《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#后台线程更新界面的更多相关文章

  1. C# 后台线程更新UI控件

    /********************************************************************************* * C# 后台线程更新UI控件 * ...

  2. 一种WPF在后台线程更新UI界面的简便方法

    WPF框架规定只有UI线程(主线程)可以更新界面,所有其他后台线程无法直接更新界面.幸好,WPF提供的SynchronizationContext类以及C#的Lambda表达式提供了一种方便的解决方法 ...

  3. WPF后台线程更新UI

    0.讲点废话 最近在做一个文件搜索的小软件,当文件多时,界面会出现假死的状况,于是乎想到另外开一个后台线程,更新界面上的ListView,但是却出现我下面的问题. 1.后台线程问题 2年前写过一个软件 ...

  4. 非UI线程更新界面

    package com.caterSys.Thread; import java.text.SimpleDateFormat; import java.util.Date; import org.ec ...

  5. Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面

    Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...

  6. Android异步处理系列文章四篇之一使用Thread+Handler实现非UI线程更新UI界面

    目录: Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+L ...

  7. C# 跨线程更新UI界面的适当的处理方式,友好的退出界面的机制探索

    本文主要讲讲C#窗体的程序中一个经常遇到的情况,就是在退出窗体的时候的,发生了退出的异常. 工业软件技术交流群:群1:592132877(满)  群2:948305931     欢迎技术探讨 我们先 ...

  8. C# Winform 窗体界面”假死”后台线程阻塞 解决办法–BeginInvoke

    原文:C# Winform 窗体界面"假死"后台线程阻塞 解决办法–BeginInvoke 这个方法可以用在任何后台任务耗时较长,造成界面“假死”界面控件不更新的情况. 比如要要执 ...

  9. 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

    在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...

随机推荐

  1. Highcharts.js -纯javasctipt图表库初体验

    一.highcharts简介以及引入 highcharts作为免费提供给个人学习.个人网站和非商业用途使用的前端图表演示插件的确使用起来十分方便和轻便.在我最近完成一个需求的时候用到了它, 它的兼容性 ...

  2. \G,sql中select 如果太长,可以在后面放\G,竖行显示~~~~

    1.使用\G按行垂直显示结果 如果一行很长,需要这行显示的话,看起结果来就非常的难受. 在SQL语句或者命令后使用\G而不是分号结尾,可以将每一行的值垂直输出. mysql> select * ...

  3. 51nod 1629 B君的圆锥

    1629 B君的圆锥 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 B君要用一个表面积为S的圆锥将白山云包起来.   B君希望包住的白山云体积尽量 ...

  4. atcoder #082 E 暴力 计算几何

    给出点集,然后求一个凸包的所有的子凸包的贡献总和,贡献计算是凸包内部含边界上点的数量N,凸包的不包含边界的顶点数S,贡献为$2^{N-S}$ 首先很容易想到,凸包上包含内部的所有点构成的子凸包有Sum ...

  5. CF821 E. Okabe and El Psy Kongroo 矩阵快速幂

    LINK 题意:给出$n$条平行于x轴的线段,终点$k$坐标$(k <= 10^{18})$,现在可以在线段之间进行移动,但不能超出两条线段的y坐标所夹范围,问到达终点有几种方案. 思路:刚开始 ...

  6. Linux高级编程--01.vi命令

    VI是Linux/Unix下标配的一个纯字符界面的文本编辑器.由于不支持鼠标功能,也没有图形界面,相关的操作都要通过键盘指令来完成,需要记忆大量命令.因此很多人不大喜欢它,但同时由于键盘的方式往往比鼠 ...

  7. 重构改善既有代码设计--重构手法05:Introduce Explaining Variable (引入解释性变量)

      发现:你有一个复杂的表达式. 解决:将该复杂的表达式(或其中的部分)的结果放进一个临时变量,并以此变量名称来解释表达式用途. //重构前 if((platform.toUpperCase().in ...

  8. ⑦ 设计模式的艺术-13.代理(Proxy)模式

    为什么需要代理模式 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口. 开闭原则,增加 ...

  9. 聊聊spring的那些扩展机制

    1.背景 慎入:本文将会有大量代码出入. 在看一些框架源码的时候,可以看见他们很多都会和Spring去做结合.举个例子dubbo的配置: 很多人其实配置了也就配置了,没有去过多的思考:为什么这么配置s ...

  10. 2017ACM暑期多校联合训练 - Team 5 1006 HDU 5205 Rikka with Graph (找规律)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...