参考文章《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. Nginx多个配置文件共用location配置

    一.应用情况 很多时候我们在一台服务器上部署了不止 一个项目,我们通过Nginx来代理,为了方便管理往往会将各个项目的配置分开写到不同的配置文件中,如: 在nginx.conf 文件中加上  incl ...

  2. php基础知识(语法与原理)

    一.php简介 PHP超文本预处理器.是嵌入HTML文件中的服务器脚本程序. PHP代码标记:<?php …. ?> PHP文件的扩展名:.php PHP文件的执行:必须从域名开始访问 P ...

  3. 写文章 使用conda管理python环境

    使用conda管理python环境

  4. 对拍 bat

    :loop maker.exe std.exe my.exe fc std.out my.out goto loop pause

  5. fastreport中文乱码问题

    fastreport的中文乱码问题,确实让人头疼,我使用的是delphi6+fastrepport4.7,在4.7版本中,主要表现在以下几种情况. 预览不乱码,保存乱码. 简体不乱码,繁体乱码. 简体 ...

  6. [php]apache虚拟主机配置

    1.所谓虚拟主机的配置,即url与磁盘目录的绑定 2.在httpd.conf中查询Virtual host,发现有注释说明需要在conf/extra/httpd-vhosts.conf中进行配置. 3 ...

  7. 【BZOJ】3992: [SDOI2015]序列统计 NTT+生成函数

    [题意]给定一个[0,m-1]范围内的数字集合S,从中选择n个数字(可重复)构成序列.给定x,求序列所有数字乘积%m后为x的序列方案数%1004535809.1<=n<=10^9,3< ...

  8. 面试C++失败

    到今天,面试已经整整一周,一个offer没有收到,mmp. 无奈,痛苦,迷茫. 以前活的太安逸,太舒适了. 自以为是,异想天开. 要重新振作起来. 要不断学习,保持强大,未来之路才会越走越宽.

  9. 使用OpenCV和Python进行人脸识别

    介绍 人脸识别是什么?或识别是什么?当你看到一个苹果时,你的大脑会立刻告诉你这是一个苹果.在这个过程中,你的大脑告诉你这是一个苹果水果,用简单的语言来说就是识别.那么什么是人脸识别呢?我肯定你猜对了. ...

  10. 原 jQuery中document的ready和load事件的区别?

    概述: 大家在工作中用jQuery的时候一定会在使用之前这样:   1 2 3 4 5 6 7 8 //document ready $(document).ready(function(){     ...