• 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;

  • 相关阅读:
    网格模型和X文件使用面面观(转)
    3D中的OBJ文件格式详解(转载)
    机器学习随笔01
    WinForm ListControl MouseWheel Envent
    如何判断一个元素在亿级数据中是否存在? 很难吗...
    windows 虚拟机VMware 安装linux系统注意事项!!!
    windows phpinfo上不能找到memcache扩展 php版本5.6
    php 判断两个时间段是否有交集
    tp5.0 根据经纬度 获取附近信息
    php 前台生成多维数组 后台批量添加
  • 原文地址:https://www.cnblogs.com/wdfrog/p/2709069.html
Copyright © 2020-2023  润新知