混料生产工单自动下发(仿真模拟器)(2):仿真测试

接上一篇我们已经对混料生产工单自动下发基础函数封装完毕,现在模拟具体的生产场景。

在windows窗体应用程序WorkOrderDemo的默认Form1重命名为FormWorkOrderSimulation

用于【仿真模拟器】生产工单混料生产自动下发

一、窗体基本设计

1).自动下发工单仿真测试窗体FormWorkOrderSimulation设计器如图:

2).工单基本信息窗体FormWorkOrderBasic设计器如图:

 3).工单生产方案窗体FormWorkOrderPlan设计器如图:

 二、窗体相关代码【忽略设计器自动生成的事件和代码】

1)FormWorkOrderBasic.cs相关源程序

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WorkOrderDemo
{
    public partial class FormWorkOrderBasic : Form
    {
        public FormWorkOrderBasic()
        {
            InitializeComponent();

            //为列绑定数据库列名称
            dgvData.AutoGenerateColumns = false;
            dgvcCoreId.DataPropertyName = "CoreId";
            dgvcWorkOrderCode.DataPropertyName = "WorkOrderCode";
            dgvcWorkOrderName.DataPropertyName = "WorkOrderName";
            dgvcWorkOrderCategory.DataPropertyName = "WorkOrderCategory";
            dgvcWorkOrderPn.DataPropertyName = "WorkOrderPn";
            dgvcOrderTotal.DataPropertyName = "WorkOrderTotal";
            dgvcRemainderCount.DataPropertyName = "RemainderCount";
            dgvcProcessEndTime.DataPropertyName = "ProcessEndTime";
        }

        /// <summary>
        /// 基本输入验证
        /// </summary>
        /// <returns></returns>
        private bool CheckInput()
        {
            if (txtWorkOrderCode.Text.Trim().Length == 0)
            {
                txtWorkOrderCode.Focus();
                MessageBox.Show("工单编号不能为空", "出错");
                return false;
            }
            int WorkOrderTotal;
            if (!int.TryParse(txtWorkOrderTotal.Text, out WorkOrderTotal) || WorkOrderTotal <= 0)
            {
                txtWorkOrderTotal.Focus();
                MessageBox.Show("工单总数不是正整数,请重新输入", "出错");
                return false;
            }
            int RemainderCount;
            if (!int.TryParse(txtRemainderCount.Text, out RemainderCount) || RemainderCount < 0)
            {
                txtRemainderCount.Focus();
                MessageBox.Show("剩余数量不是正整数,请重新输入", "出错");
                return false;
            }
            return true;
        }

        private void FormWorkOrderBasic_Load(object sender, EventArgs e)
        {
            try
            {
                DataTable dt = WorkOrderUtil.GetAllWorkOrderBasic();
                dgvData.DataSource = dt;
            }
            catch (Exception ex)
            {
                string msg = $"读取工单基本信息失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "读取工单信息");
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (!CheckInput())
            {
                return;
            }
            btnSave.Enabled = false;
            try
            {
                WorkOrderBasic workOrderBasic = new WorkOrderBasic();
                workOrderBasic.WorkOrderCode = txtWorkOrderCode.Text;
                workOrderBasic.WorkOrderName = txtWorkOrderName.Text;
                workOrderBasic.WorkOrderCategory = txtWorkOrderCategory.Text;
                workOrderBasic.WorkOrderPn = txtWorkOrderPn.Text;
                workOrderBasic.ProcessEndTime = DateTime.Now;
                workOrderBasic.WorkOrderTotal = int.Parse(txtWorkOrderTotal.Text);
                workOrderBasic.RemainderCount = int.Parse(txtRemainderCount.Text);
                WorkOrderUtil.SaveWorkOrderBasic(workOrderBasic);

                btnSave.Enabled = true;
                string msg = $"保存工单基本信息完成!\n工单编号-【{txtWorkOrderCode.Text}】\n";
                FormWorkOrderBasic_Load(null, null);
                MessageBox.Show(msg, "保存工单结果");
            }
            catch (Exception ex)
            {
                btnSave.Enabled = true;
                string msg = $"保存工单基本信息失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "保存工单结果");
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            string workOrderCode = txtWorkOrderCode.Text.Trim();
            if (workOrderCode.Length == 0)
            {
                txtWorkOrderCode.Focus();
                MessageBox.Show("工单编号不能为空", "出错");
                return;
            }
            try
            {
                int result = WorkOrderUtil.DeleteWorkOrderBasic(workOrderCode);
                if (result == -1)
                {
                    MessageBox.Show($"工单正在被使用,无法删除\n工单编号-【{workOrderCode}】", "删除工单结果");
                    return;
                }

                string msg = $"删除工单基本信息完成!\n工单编号-【{workOrderCode}】\n";
                FormWorkOrderBasic_Load(null, null);
                MessageBox.Show(msg, "删除工单结果");
            }
            catch (Exception ex)
            {
                string msg = $"删除工单基本信息失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "删除工单结果");
            }
        }

        private void btnAddMaterial_Click(object sender, EventArgs e)
        {
            if (txtWorkOrderCodeUpdate.Text.Trim().Length == 0)
            {
                txtWorkOrderCodeUpdate.Focus();
                MessageBox.Show("工单编号不能为空", "出错");
                return;
            }
            int RemainderCount;
            if (!int.TryParse(txtRemainderCountUpdate.Text, out RemainderCount) || RemainderCount < 0)
            {
                txtRemainderCountUpdate.Focus();
                MessageBox.Show("剩余数量不是正整数,请重新输入", "出错");
                return;
            }

            try
            {
                WorkOrderUtil.UpdateWorkOrderRemainder(txtWorkOrderCodeUpdate.Text.Trim(), RemainderCount);

                string msg = $"更新工单剩余数量【库存】完成!\n工单编号-【{txtWorkOrderCodeUpdate.Text}】,当前数量【{RemainderCount}】\n";
                FormWorkOrderBasic_Load(null, null);
                MessageBox.Show(msg, "更新工单库存");
            }
            catch (Exception ex)
            {
                string msg = $"更新工单剩余数量【库存】失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "更新工单库存");
            }
        }

        private void dgvData_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView gridView = sender as DataGridView;
            int index = e.RowIndex;
            if (index < 0 || index > gridView.RowCount - 1)
                return;
            txtWorkOrderCode.Text = gridView.Rows[index].Cells[1].Value.ToString();
            txtWorkOrderName.Text = gridView.Rows[index].Cells[2].Value.ToString();
            txtWorkOrderCategory.Text = gridView.Rows[index].Cells[3].Value.ToString();
            txtWorkOrderPn.Text = gridView.Rows[index].Cells[4].Value.ToString();
            txtWorkOrderTotal.Text = gridView.Rows[index].Cells[5].Value.ToString();
            txtRemainderCount.Text = gridView.Rows[index].Cells[6].Value.ToString();

            txtWorkOrderCodeUpdate.Text = gridView.Rows[index].Cells[1].Value.ToString();
            txtRemainderCountUpdate.Text = gridView.Rows[index].Cells[6].Value.ToString();
        }

        private void dgvData_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            dgvData_CellContentClick(dgvData, e);
        }
    }
}

2)FormWorkOrderPlan.cs相关源程序

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WorkOrderDemo
{
    public partial class FormWorkOrderPlan : Form
    {
        /// <summary>
        /// 刷新当前工单和下一工单事件。第一个元组代表当前工单,第二个元组代表下一工单
        /// </summary>
        public event Action<Tuple<string, string, string, string>, Tuple<string, string, string, string>> EventRefreshWorkOrder;
        public FormWorkOrderPlan()
        {
            InitializeComponent();

            //周期工单数CycleCount
            cboCycleCount.SelectedIndex = 3;//默认是AB
            //只有工单编号可以编辑,其他列不可编辑
            dgvc1.ReadOnly = true;//顺序号不可编辑
            dgvc3.ReadOnly = true;
            dgvc4.ReadOnly = true;
            dgvc5.ReadOnly = true;
            dgvc6.ReadOnly = true;
            dgvc7.ReadOnly = true;

            dgvData.AutoGenerateColumns = false;
            dgvcCoreId.DataPropertyName = "CoreId";
            dgvcPlanCode.DataPropertyName = "PlanCode";
            dgvcPlanName.DataPropertyName = "PlanName";
            dgvcPlanSequence.DataPropertyName = "PlanSequence";
            dgvcOrderCode.DataPropertyName = "OrderCode";
            dgvcOrderName.DataPropertyName = "OrderName";
            dgvcWorkOrderCategory.DataPropertyName = "WorkOrderCategory";
            dgvcWorkOrderPn.DataPropertyName = "WorkOrderPn";
            dgvcOrderTotal.DataPropertyName = "OrderTotal";
            dgvcRemainderCount.DataPropertyName = "RemainderCount";
            dgvcProcessEndTime.DataPropertyName = "ProcessEndTime";
        }

        private void FormWorkOrderDistribution_Load(object sender, EventArgs e)
        {
            try
            {
                BindHistoryOrderToGridView();
                ReadCurrentOrderPlan();
                //加载完之后再触发索引改变事件
                cboCycleCount.SelectedIndexChanged += CboCycleCount_SelectedIndexChanged;
            }
            catch (Exception ex)
            {
                string msg = $"读取历史生产方案失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "读取历史工单");
            }
        }
        private void CboCycleCount_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboCycleCount.SelectedIndex == -1)
            {
                return;
            }
            dgvPlanDetail.Rows.Clear();
            int cycleCount = Convert.ToInt32(cboCycleCount.SelectedItem);
            for (int i = 0; i < cycleCount; i++)
            {
                dgvPlanDetail.Rows.Add(i + 1, "", "A", "XPXS", "123456-66666", "100", "100");
            }
        }

        /// <summary>
        /// 绑定历史生产工单到网格视图
        /// </summary>
        private void BindHistoryOrderToGridView()
        {
            DataTable dt = WorkOrderUtil.GetHistoryOrderPlan();
            dgvData.DataSource = dt;
        }

        /// <summary>
        /// 读取当前工单方案,也可以用于刷新工单剩余数量
        /// 刷新显示剩余数量,当自动下发工单时,剩余数量刷新
        /// </summary>
        public void ReadCurrentOrderPlan()
        {
            List<WorkOrderPlanDetail> list = WorkOrderUtil.GetCurrentOrderPlan();
            for (int i = 0; i < cboCycleCount.Items.Count; i++)
            {
                if (Convert.ToInt32(cboCycleCount.Items[i]) == list.Count)
                {
                    cboCycleCount.SelectedIndex = i;
                    break;
                }
            }
            dgvPlanDetail.Rows.Clear();
            if (list.Count > 0)
            {
                txtPlanCode.Text = list[0].PlanCode;
                txtPlanName.Text = list[0].PlanName;
                for (int i = 0; i < list.Count; i++)
                {
                    dgvPlanDetail.Rows.Add(i + 1, list[i].OrderCode, list[i].OrderName, list[i].WorkOrderCategory,
                        list[i].WorkOrderPn, list[i].OrderTotal, list[i].RemainderCount);
                }
            }
        }

        private void btnWorkOrderEdit_Click(object sender, EventArgs e)
        {
            FormWorkOrderBasic formWorkOrderBasic = new FormWorkOrderBasic();
            formWorkOrderBasic.ShowDialog();
            //刷新当前工单方案剩余工单数量
            ReadCurrentOrderPlan();
            WorkOrderUtil.RefreshCurrentAndNextWorkOrder(EventRefreshWorkOrder);
        }

        /// <summary>
        /// 基本输入数据过滤
        /// </summary>
        /// <returns></returns>
        private bool CheckInput()
        {
            if (cboCycleCount.SelectedIndex == -1 || dgvPlanDetail.Rows.Count == 0)
            {
                cboCycleCount.Focus();
                MessageBox.Show("请选择工单周期数 以及 设定相应的工单信息", "异常");
                return false;
            }
            List<string> listWorkOrder = new List<string>();
            for (int i = 0; i < dgvPlanDetail.Rows.Count; i++)
            {
                string OrderCode = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc2"].Value);
                string OrderName = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc3"].Value);
                string OrderTotal = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc6"].Value);
                string RemainderCount = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc7"].Value);

                listWorkOrder.Add(OrderCode);
                if (string.IsNullOrWhiteSpace(OrderCode))
                {
                    dgvPlanDetail.Rows[i].Cells["dgvc2"].Selected = true;
                    MessageBox.Show("工单编号不能为空", "异常");
                    return false;
                }
                if (string.IsNullOrWhiteSpace(OrderName))
                {
                    dgvPlanDetail.Rows[i].Cells["dgvc3"].Selected = true;
                    MessageBox.Show("工单标记不能为空", "异常");
                    return false;
                }
                int orderTotal;
                int remainderCount;
                if (!int.TryParse(OrderTotal, out orderTotal) || orderTotal < 0)
                {
                    dgvPlanDetail.Rows[i].Cells["dgvc6"].Selected = true;
                    MessageBox.Show("工单总数必须是数字并且不小于0,请重新输入", "异常");
                    return false;
                }
                if (!int.TryParse(RemainderCount, out remainderCount) || remainderCount < 0)
                {
                    dgvPlanDetail.Rows[i].Cells["dgvc7"].Selected = true;
                    MessageBox.Show("剩余数量必须是数字并且不小于0,请重新输入", "异常");
                    return false;
                }
            }
            //工单编号必须存在
            for (int i = 0; i < listWorkOrder.Count; i++)
            {
                string workOrderCode = listWorkOrder[i];
                DataTable dt = WorkOrderUtil.GetWorkOrderBasic(workOrderCode);
                if (dt == null || dt.Rows.Count == 0)
                {
                    MessageBox.Show($"没有配置工单号【{workOrderCode}】的基本信息,请重新输入工单号", "异常");
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 当前选定单元格【工单编号】的编辑模式停止时发生。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvPlanDetail_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex != 1)
            {
                //只编辑工单编号列
                return;
            }
            string workOrderCode = Convert.ToString(dgvPlanDetail.Rows[e.RowIndex].Cells[1].Value);
            DataTable dt = WorkOrderUtil.GetWorkOrderBasic(workOrderCode);
            if (dt == null || dt.Rows.Count == 0)
            {
                dgvPlanDetail.Rows[e.RowIndex].Cells[1].Selected = true;
                MessageBox.Show($"没有配置工单号【{workOrderCode}】的基本信息,请重新输入工单号", "异常");
                return;
            }
            DataRow dataRow = dt.Rows[0];
            dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc3"].Value = dataRow["WorkOrderName"].ToString();
            dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc4"].Value = dataRow["WorkOrderCategory"].ToString();
            dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc5"].Value = dataRow["WorkOrderPn"].ToString();
            dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc6"].Value = dataRow["WorkOrderTotal"].ToString();
            dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc7"].Value = dataRow["RemainderCount"].ToString();
        }

        private void btnSetPlan_Click(object sender, EventArgs e)
        {
            if (!CheckInput())
            {
                return;
            }
            //自动设置生产方案代码、生产方案名称
            List<string> listPlanCode = new List<string>();
            for (int i = 0; i < dgvPlanDetail.Rows.Count; i++)
            {
                string OrderName = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc3"].Value);
                listPlanCode.Add(OrderName);
            }
            txtPlanCode.Text = string.Join("-", listPlanCode);
            //一个托盘有两个电芯
            txtPlanName.Text = $"轮回工单个数【{int.Parse(cboCycleCount.Text)}】【{string.Join("-", listPlanCode)}】";
            //周期工单数CycleCount
            //WorkOrderPlanDetail详细表
            //比如方案序号是【1,2,3,4】
            //第一次【1】作为当前工单号 【2】作为预设工单号
            //第二次【2】作为当前工单号 【3】作为预设工单号
            //第三次【3】作为当前工单号 【4】作为预设工单号
            //第四次【4】作为当前工单号 【1】作为预设工单号
            //第五次 和 第一次 一样

            btnSetPlan.Enabled = false;
            try
            {
                WorkOrderPlan workOrderPlan = new WorkOrderPlan();
                workOrderPlan.PlanCode = txtPlanCode.Text;
                workOrderPlan.PlanName = txtPlanName.Text;
                workOrderPlan.CycleCount = int.Parse(cboCycleCount.Text);
                workOrderPlan.ProcessEndTime = DateTime.Now;

                List<WorkOrderPlanDetail> workOrderPlanDetails = new List<WorkOrderPlanDetail>();
                Queue<string> queue = new Queue<string>();
                for (int i = 0; i < dgvPlanDetail.Rows.Count; i++)
                {
                    queue.Enqueue(Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc2"].Value));

                    WorkOrderPlanDetail workOrderPlanDetail = new WorkOrderPlanDetail();
                    workOrderPlanDetail.PlanSequence = i + 1;
                    workOrderPlanDetail.OrderCode = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc2"].Value);
                    workOrderPlanDetail.OrderName = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc3"].Value);
                    workOrderPlanDetail.WorkOrderCategory = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc4"].Value);
                    workOrderPlanDetail.WorkOrderPn = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc5"].Value);
                    workOrderPlanDetail.OrderTotal = Convert.ToInt32(dgvPlanDetail.Rows[i].Cells["dgvc6"].Value);
                    workOrderPlanDetail.RemainderCount = Convert.ToInt32(dgvPlanDetail.Rows[i].Cells["dgvc7"].Value);
                    workOrderPlanDetails.Add(workOrderPlanDetail);
                }
                WorkOrderUtil.EnableOrderPlan(workOrderPlan, workOrderPlanDetails);

                btnSetPlan.Enabled = true;
                string msg = $"设置当前生产方案【{txtPlanCode.Text}】成功!\n工单队列【{string.Join("-", queue)}】";
                BindHistoryOrderToGridView();
                WorkOrderUtil.RefreshCurrentAndNextWorkOrder(EventRefreshWorkOrder);
                MessageBox.Show(msg, "设置当前生产方案");
            }
            catch (Exception ex)
            {
                btnSetPlan.Enabled = true;
                string msg = $"设置当前生产方案失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "设置当前生产方案");
            }
        }

        private void btnReadPlan_Click(object sender, EventArgs e)
        {
            ReadCurrentOrderPlan();
        }

        private void btnSearchHistory_Click(object sender, EventArgs e)
        {
            try
            {
                BindHistoryOrderToGridView();
            }
            catch (Exception ex)
            {
                string msg = $"读取历史生产方案失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "读取历史工单");
            }
        }

        private void btnClearHistory_Click(object sender, EventArgs e)
        {
            DialogResult dialog = MessageBox.Show("您确定要一键清除历史工单方案?\n清除后,可适当优化【工单发放】性能!", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (dialog != DialogResult.Yes)
            {
                return;
            }
            try
            {
                WorkOrderUtil.ClearHistoryOrderPlan();
                BindHistoryOrderToGridView();
                string msg = $"一键清除历史工单方案成功!";
                MessageBox.Show(msg, "清除历史工单方案");
            }
            catch (Exception ex)
            {
                string msg = $"清除历史工单方案失败!\n错误原因-【{ex.Message}】";
                MessageBox.Show(msg, "清除历史工单方案");
            }
        }
    }
}

3)FormWorkOrderSimulation.cs相关源程序

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WorkOrderDemo
{
    public partial class FormWorkOrderSimulation : Form
    {
        /// <summary>
        /// 是否已启动线程
        /// </summary>
        bool isRun = false;
        /// <summary>
        /// 仿真任务:每隔5秒就自动下发一个工单。当某一个工单剩余数量为0时,自动停止
        /// </summary>
        Task task;
        public FormWorkOrderSimulation()
        {
            InitializeComponent();
            //初始化创建数据库
            SqliteAssist.IniDataTable();
        }

        private void FormWorkOrderSimulation_Load(object sender, EventArgs e)
        {
            //读取当前工单和下一工单
            WorkOrderUtil.RefreshCurrentAndNextWorkOrder(EventProcess_EventRefreshWorkOrder);
        }

        private void btnStartSimulation_Click(object sender, EventArgs e)
        {
            isRun = !isRun;
            SetButtonStatus(isRun);
            task = Task.Factory.StartNew(() => 
            {
                while (isRun)
                {
                    try
                    {
                        DisplayInfo($"【请求工单和预设工单】触发:开始处理释放工单事务...");
                        string errMsg;
                        DataTable dtSequence;
                        bool result = WorkOrderUtil.GetNextAndPresetWorkOrder(out errMsg, out dtSequence);
                        if (!result || dtSequence == null)
                        {
                            DisplayInfo($"【请求工单和预设工单】发送工单失败,出现错误 或 无法获取当前工单.{errMsg}");
                            isRun = false;
                            SetButtonStatus(isRun);
                            return;
                        }
                        //有两行,当前工单 和 下一个预设工单
                        if (dtSequence.Rows.Count != 2)
                        {
                            DisplayInfo($"【请求工单和预设工单】发送工单失败,当前工单 和 预设工单的记录总数不是两行,实际【{dtSequence.Rows.Count }】行数据");
                            isRun = false;
                            SetButtonStatus(isRun);
                            return;
                        }
                        DataRow drSequence = dtSequence.Rows[0];
                        DataRow drPreset = dtSequence.Rows[1];
                        string WorkOrderCode = drSequence["OrderCode"].ToString();
                        string RemainderCount = drSequence["RemainderCount"].ToString();
                        string PlanSequence = drSequence["PlanSequence"].ToString(); 
                        string WorkOrderCategory = drSequence["WorkOrderCategory"].ToString();

                        //预设工单信息
                        string NextWorkOrderCode = drPreset["OrderCode"].ToString();
                        string NextRemainderCount = drPreset["RemainderCount"].ToString();
                        string NextPlanSequence = drPreset["PlanSequence"].ToString();
                        string NextWorkOrderCategory = drPreset["WorkOrderCategory"].ToString();
                        DisplayInfo($"【请求工单和预设工单】操作成功,当前工单号【{WorkOrderCode}】,剩余数量【{RemainderCount}】,顺序号【{PlanSequence}】,产品类型【{WorkOrderCategory}】");
                        DisplayInfo($"【请求工单和预设工单】操作成功,下一工单号【{NextWorkOrderCode}】,剩余数量【{NextRemainderCount}】,顺序号【{NextPlanSequence}】,产品类型【{NextWorkOrderCategory}】");

                        //刷新前台界面
                        EventProcess_EventRefreshWorkOrder(Tuple.Create(WorkOrderCode, RemainderCount, PlanSequence, WorkOrderCategory), Tuple.Create(NextWorkOrderCode, NextRemainderCount, NextPlanSequence, NextWorkOrderCategory));
                    }
                    catch (Exception ex)
                    {
                        DisplayInfo($"【请求工单和预设工单】出现异常【{ex.Message}】");
                        isRun = false;
                        SetButtonStatus(isRun);
                        return;
                    }
                    Thread.Sleep(5000);
                }
            });
        }
        FormWorkOrderPlan formWorkOrderPlan;
        private void btnEditPlan_Click(object sender, EventArgs e)
        {
            if (isRun)
            {
                MessageBox.Show("请先停止下发工单线程,方可编辑工单生产方案", "非法操作");
                return;
            }
            if (formWorkOrderPlan == null || formWorkOrderPlan.IsDisposed)
            {
                formWorkOrderPlan = new FormWorkOrderPlan();
                formWorkOrderPlan.EventRefreshWorkOrder -= EventProcess_EventRefreshWorkOrder;
                formWorkOrderPlan.EventRefreshWorkOrder += EventProcess_EventRefreshWorkOrder;
                formWorkOrderPlan.Show();
            }
            else
            {
                formWorkOrderPlan.Activate();
            }
        }

        /// <summary>
        /// 显示文本框的消息
        /// </summary>
        /// <param name="message"></param>
        private void DisplayInfo(string message)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (rtxbResult.TextLength >= 20480)
                {
                    rtxbResult.Clear();
                }
                rtxbResult.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} --> {message}\n");
                rtxbResult.ScrollToCaret();
            }));
        }

        private void SetButtonStatus(bool isRunning)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (isRunning)
                {
                    btnStartSimulation.Text = "停止工单下发(仿真)";
                    DisplayInfo($"【下发工单】线程已启动...");
                }
                else
                {
                    btnStartSimulation.Text = "启动工单下发(仿真)";
                    DisplayInfo($"【下发工单】线程已停止...");
                }
            }));
        }

        /// <summary>
        /// 刷新当前工单和下一工单,同时刷新工单剩余数量【工单生产方案界面】
        /// </summary>
        /// <param name="tupleCurrentWorkOrder">当前工单方案信息</param>
        /// <param name="tupleNextWorkOrder">下一工单方案信息</param>
        private void EventProcess_EventRefreshWorkOrder(Tuple<string, string, string, string> tupleCurrentWorkOrder, Tuple<string, string, string, string> tupleNextWorkOrder)
        {
            try
            {
                this.BeginInvoke(new Action(() =>
                {
                    txtCurrentOrder.Text = tupleCurrentWorkOrder.Item1;
                    txtRemainderCount.Text = tupleCurrentWorkOrder.Item2;
                    txtPlanSequence.Text = tupleCurrentWorkOrder.Item3;
                    txtWorkOrderCategory.Text = tupleCurrentWorkOrder.Item4;
                    txtNextOrder.Text = tupleNextWorkOrder.Item1;
                    txtNextRemainderCount.Text = tupleNextWorkOrder.Item2;
                    txtNextPlanSequence.Text = tupleNextWorkOrder.Item3;
                    txtNextWorkOrderCategory.Text = tupleNextWorkOrder.Item4;

                    formWorkOrderPlan?.ReadCurrentOrderPlan();
                }));
            }
            catch (Exception ex)
            {
                MessageBox.Show($"当前工单刷新错误:{ex.Message}");
            }
        }
        

        private void FormWorkOrderSimulation_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isRun)
            {
                DialogResult dialog = MessageBox.Show("下发工单线程进行中!您确定要关闭该应用程序吗?", "警告", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                if (dialog != DialogResult.Yes)
                {
                    e.Cancel = true;
                    return;
                }
            }
            //线程标记清除
            isRun = false;
            task?.Wait(5000);
            Application.Exit();
        }
    }
}

三、程序运行效果如图:

1).设置新方案

 2).启动工单下发

 3).无法下发工单时,自动停止。

此时可以重新设置工单计划 或者 修改库存剩余数量(上料)

猜你喜欢

转载自blog.csdn.net/ylq1045/article/details/120250609