zoukankan      html  css  js  c++  java
  • BackgroundWorker使用备忘

    UI类似下面,带进度条与提示信息

     任务类代码

    View Code
        /// <summary>
        /// 利润分析类
        /// </summary>
        public class ProfitAnalys
        {
            public ProfitAnalys(BackgroundWorker worker, DateTime bTime, DateTime eTime)
            {
                this.Worker = worker;
                this.BTime = bTime;
                this.ETime = eTime;
            }
    
            /// <summary>
            /// 材料每吨锻造费用
            /// </summary>
            public decimal? DealFeePerT { get; set; }
            /// <summary>
            /// 钢料每吨价格
            /// </summary>
            public decimal? MPricePerT { get; set; }
    
            public DateTime BTime { get; set; }
            public DateTime ETime { get; set; }
            private BackgroundWorker Worker { get; set; }
            private void Report(int progress, ReportInfo data)
            {
                if (Worker == null) return;
                Worker.ReportProgress(progress, data);
            }
            public BaseProfit Do()
            {
                    string bTimeStr = BTime.ToString("yyyy-MM-dd");
                    string eTimeStr = ETime.Date.ToString("yyyy-MM-dd HH:mm:ss");
                    var cmdText="";
                    var sql="";
    
                   
                    //获取材料价格(元/吨)
                    var mPrice = MPricePerT;
                    if (!(mPrice > 0)) throw new Exception("未提供钢材价格!");
    
                    #region 为协库材料价值计算
                    //获取外协库存
                    Report(10, new ReportInfo() { Msg = "获取外协材料库存!" });
                    cmdText = CtxFactory.GetSql(69);
                    sql = cmdText.Replace("$BDate", bTimeStr).Replace("$EDate", eTimeStr);
                    var mOutInventory = ExecSql<MInventory>(sql);
                    //外协库材料价值
                    Report(30, new ReportInfo() { Msg = "计算外协库材料价值" });
                    var MInventoryWorth = 0.0m;
                    if (mOutInventory.Count > 0)
                    {
                        MInventoryWorth = mOutInventory[0].BalanceQty.Value * mPrice.Value;
                    }
                    #endregion
    
                    #region 在制品材料价值计算
                    //获取在制产品数量列表
                    Report(50, new ReportInfo() { Msg = "获取在制产品数量列表" });
                    cmdText = CtxFactory.GetSql(68);
                    sql = cmdText.Replace("$BDate", bTimeStr).Replace("$EDate", eTimeStr).Replace("$Condition", "");
                    var pList = ExecSql<PInventory>(sql).Where(ent => ent.BalanceQty > 0).ToList();
                    //获在制品重量
                    Report(60, new ReportInfo() { Msg = "获取在产品档案数据" });
                    sql = "select RTrim(p_Partno) MNo,RTrim(p_partName) MName ,p_Weight_mp Weight from p_partno_rm";
                    var pWeightList = ExecSql<PWeight>(sql);
                    //换算在制产品材料重量
                    Report(70, new ReportInfo() { Msg = "获取在产品档案数据" });
                    var tmpList = pList.Join(pWeightList, p => p.MNo.Trim(), w => w.MNo.Trim(), (p, w) => new { Weight = w.Weight, MNo = p.MNo, MName = p.MName, Qty = p.BalanceQty }).ToList();
                    //确保设置了产品单重检测
                    tmpList.ForEach(ent =>
                    {
                        if (!(ent.Weight > 0))
                        {
                            throw new Exception(string.Format("物料:{0}没在[产品档案]中设定有效的重量参数!", ent.MNo.Trim()));
                        }
                    });
                
                    //计算在制产品材料价值
                    var pTotalWeight = (tmpList.Select(ent => ent.Qty * ent.Weight).Sum()) / 1000;//成品材料总重量(单位:吨)
                    if(!(DealFeePerT >0))throw new Exception("未提供材料锻造费用!");
    
                    var pWorth= pTotalWeight * mPrice.Value + pTotalWeight * DealFeePerT.Value ;
                    #endregion
                
                     //费用,销售,材料成本,锻造等费用
                    Report(90, new ReportInfo() { Msg = "计算销售、材料、运费、费用等汇总金额..." });
    
                    cmdText = CtxFactory.GetSql(70);
                    sql = cmdText.Replace("$BDate", bTimeStr).Replace("$EDate", eTimeStr);
                    var profitList = ExecSql<BaseProfit>(sql);
                    var profit=profitList[0];
                    profit.MInventoryMoney=MInventoryWorth;
                    profit.WIPMoney=pWorth;
                    return profit;
            }
            /// <summary>
            /// 获取材料单吨价格
            /// </summary>
            /// <param name="bTime"></param>``
            /// <param name="eTime"></param>
            /// <returns></returns>
            public decimal GetPrice(DateTime eTime)
            {
                string cmdText = "select Top 1 unitPrice from dbo.SERP_RMInticket where ptype='材料' Order By ABS(datediff(hh,DealTime,'{0}')) ASC";
                var sql = string.Format(cmdText, eTime.Date.ToString("yyyy-MM-dd HH:mm:ss"));
                var list = ExecSql<decimal>(sql);
                if (list.Count <= 0 )
                {
                    throw new Exception("无法获取有效的材料价格信息!");
                }
                return list[0];
            }
            private List<T> ExecSql<T>(string sql)
            {
                using (DB ctx = CtxFactory.New())
                {
                    ctx.CommandTimeout = 9999;
                    return ctx.ExecuteStoreQuery<T>(sql).ToList();
                }
    
            }
    
    
        }
        #region 结构类
        public class ReportInfo
        {
            public string Msg { get; set; }
            public int MsgType { get; set; }
            public object Data { get; set; }
        }
        public class BaseProfit
        {
            #region 收入类
            /// <summary>
            /// 铁削销售收入
            /// </summary>
            public decimal? SWInMoney { get; set; }
            /// <summary>
            /// 销售收入
            /// </summary>
            public decimal? InMoney { get; set; }
    
            /// <summary>
            /// 材料库存价值
            /// </summary>
            public decimal? MInventoryMoney { get; set; }
            /// <summary>
            /// 在制品价值
            /// </summary>
            public decimal? WIPMoney { get; set; }
            #endregion
            #region 成本类
            /// <summary>
            /// 材料成本
            /// </summary>
            public decimal? Cost { get; set; }
            /// <summary>
            /// 费用
            /// </summary>
            public decimal? Fee { get; set; }
            /// <summary>
            /// 工资
            /// </summary>
            public decimal? Salary { get; set; }
            /// <summary>
            /// 主运费
            /// </summary>
            public decimal? TranCost { get; set; }
            /// <summary>
            /// 锻造费用
            /// </summary>
            public decimal? DealCost { get; set; }
            #endregion
    
            public decimal? ProfitMoney
            {
                get
                {
                    return V(SWInMoney) + V(InMoney) + V(MInventoryMoney) + V(WIPMoney)
                           - V(Cost) - V(Fee) - V(Salary) - V(TranCost) - V(DealCost);
                }
            }
            private decimal V(decimal? v)
            {
                return v.HasValue ? v.Value : 0;
            }
    
        }
        public class MInventory
        {
            public string MNo { get; set; }
            public string MName { get; set; }
            public decimal? BefQty { get; set; }
            public decimal? InQty { get; set; }
            public decimal? OutQty { get; set; }
            public decimal? BalanceQty { get; set; }
        }
        public class PInventory
        {
            public string MNo { get; set; }
            public string MName { get; set; }
            public decimal? BalanceQty { get; set; }
    
        }
        public class PWeight
        {
            public string MNo { get; set; }
            public string MName { get; set; }
            public decimal? Weight { get; set; }
        }
    
    #endregion
    UI代码
    View Code
        using Report;
        using Microsoft.Reporting.WinForms;
        using EFModel;
    
        public partial class frmProfitAnalys : Form
        {
            private BackgroundWorker Worker { get; set; }
            public frmProfitAnalys()
            {
                InitializeComponent();
            }
      
            private void btnAnalys_Click(object sender, EventArgs e)
            {
    
                try
                {
                  
                    btnAnalys.Enabled = false;
                    progressBar.Value = 0;
                    lblTip.Text = "任务启动";
                    baseProfitBindingSource.DataSource = new BaseProfit();
                    this.Refresh();
                    
    
                    Worker = new BackgroundWorker();
                    Worker.WorkerReportsProgress = true;
                    Worker.WorkerSupportsCancellation = true;
    
                    var bTime = dtpBTime.Value.Date;
                    var eTime = dtpETime.Value.Date.AddHours(23.9999);
                    var analyst = new ProfitAnalys(Worker, bTime, eTime);
                    if (!ckbIsCustomer.Checked)
                    {
                        this.Refresh();
                        var mPrice_ = 0.0m;
                        mPrice_ = analyst.GetPrice(eTime);
                        txtMPrice.Text = mPrice_.ToString("0.00");
                    }
    
                    decimal mPrice = 0.0m;
                    decimal.TryParse(txtMPrice.Text, out mPrice);
                    if (!(mPrice > 0)) throw new Exception("请提供有效的材料价格!");
                    analyst.MPricePerT = mPrice;//设置价格
    
                    decimal dealFee = 0.0m;
                    decimal.TryParse(txtDealFee.Text, out dealFee);
                    if (!(dealFee > 0)) throw new Exception("请提供有效的锻造费!");
                    analyst.DealFeePerT = dealFee;//设置锻造费用
    
                    #region 异步执行配置
                    Worker.DoWork += (s, e1) =>
                    {
    
                       //如果要RunWorkerCompleted中的e1.Cancelled为true
                       //那么必需在这里设置e1.Cancel=true,只调用Worker.CancelAsync不会使上面的e1.Cancell为true
                       //调用Worker.CancelAsync();会设置Worker.CancellationPending=true;
                       //可以在Do中判断CancellationPending以决定是否取消处理
                       //如果用户提交了取消则Do返回一个取消的标识对象,在这里做下判断,后设置e1.Cancel=true;
                        e1.Result = analyst.Do();
    
                        
                    };
                    //进度报告
                    Worker.ProgressChanged += (s, e1) =>
                    {
                        var rpt = e1.UserState as ReportInfo;
                        if (rpt != null)
                        {
                            progressBar.Value = e1.ProgressPercentage;
                            lblTip.Text = rpt.Msg;
                           
                        }
                    };
                    Worker.RunWorkerCompleted += (s, e1) =>
                    {
                        if (e1.Cancelled)
                        {
                            lblTip.Text = "任务被取消!";
                          
                        }
                        else if (e1.Error != null)
                        {
                            lblTip.Text = "错误:" + e1.Error.Message;
                           
                        }
                        else if (e1.Result != null)
                        {
                            baseProfitBindingSource.DataSource = e1.Result;
                            baseProfitBindingSource.ResetBindings(false);
                            progressBar.Value = 100;
                            lblTip.Text = "任务完成!";
                        }
    
                        btnAnalys.Enabled = true;
    
                    };
                    Worker.RunWorkerAsync();
                    Thread.Sleep(10);
                    Worker.CancelAsync();
                    #endregion
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    btnAnalys.Enabled = true;
                }
    
    
            }
    
            private void frmProfitAnalys_Load(object sender, EventArgs e)
            {
                txtMPrice.Enabled = false;
                ckbIsCustomer.Checked = false;
                ckbIsCustomer.Click += (s, e1) =>
                {
                    if (!ckbIsCustomer.Checked)
                    {
                        txtMPrice.Text = string.Empty;
    
                    }
                    txtMPrice.Enabled = ckbIsCustomer.Checked;
                };
    
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
                this.MinimizeBox = false;
                this.MaximizeBox = false;
    
            }
        }

    关于取消任务的说明
    如果要RunWorkerCompleted中的e1.Cancelled为true
    那么必需在这里设置e1.Cancel=true,只调用Worker.CancelAsync不会使上面的e1.Cancell为true
    调用Worker.CancelAsync();会设置Worker.CancellationPending=true;
    可以在Do中判断CancellationPending以决定是否取消处理
    如果用户提交了取消则Do返回一个取消的标识对象,在这里做下判断,后设置e1.Cancel=true;

  • 相关阅读:
    Codeforces 1485C Floor and Mod (枚举)
    CodeForces 1195D Submarine in the Rybinsk Sea (算贡献)
    CodeForces 1195C Basketball Exercise (线性DP)
    2021年初寒假训练第24场 B. 庆功会(搜索)
    任务分配(dp)
    开发工具的异常现象
    Telink MESH SDK 如何使用PWM
    Telink BLE MESH PWM波的小结
    [LeetCode] 1586. Binary Search Tree Iterator II
    [LeetCode] 1288. Remove Covered Intervals
  • 原文地址:https://www.cnblogs.com/wdfrog/p/2709069.html
Copyright © 2011-2022 走看看