C/S 进度条和跨页面传值的联合使用

本文介绍了一种在C/S架构项目中实现进度条的方法,通过BackgroundWorker组件进行后台任务处理,有效提升用户体验。文中详细展示了如何创建进度条窗口、配置参数及调用流程,并通过具体实例解释了文件预处理过程。

在C/S项目中,通常会遇到一些耗时的操作,这个时候为了更好的客户体验,我们通常会加上一个进度条。 而且页面传值在C/S端也比较麻烦。毕竟不像B/S那样可以使用Session、QueryString、Cookie,或者提交表格等那么方便。

开始了:
这里写图片描述
页面很简单, 同样这里还有一个backgroundWorker类

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace QuickLogisticsAssistant
{
    public partial class BackgroundWorkerView : Form
    {
        public delegate void Action<in T1, in T2>(T1 arg1,T2 arg2);

        public Action<BackgroundWorker, DoWorkEventArgs> DoWork { get; private set; }
        public Action<BackgroundWorker, RunWorkerCompletedEventArgs> RunWorkerCompleted { get; private set; }
        public RunWorkerCompletedEventArgs ExecutionResult { get; private set; }
        public ApartmentState ThreadApartmentState { get; set; }

        public BackgroundWorkerView(Action<BackgroundWorker, DoWorkEventArgs> doWork, Action<BackgroundWorker, RunWorkerCompletedEventArgs> runWorkerCompleted = null)
        {
            this.ThreadApartmentState = ApartmentState.MTA;
            InitializeComponent();
            this.Text = string.Format("{0} - 正在执行操作...", Application.ProductName);

            this.DoWork = doWork;
            this.RunWorkerCompleted = runWorkerCompleted;

            this.progressBar1.Style = ProgressBarStyle.Marquee;
        }

        public BackgroundWorkerView(string title, Action<BackgroundWorker, DoWorkEventArgs> doWork, Action<BackgroundWorker, RunWorkerCompletedEventArgs> runWorkerCompleted = null)
        {
            this.ThreadApartmentState = ApartmentState.MTA;
            InitializeComponent();
            //this.Text = string.Format("正在{0}...", title);
            this.Text = title;

            this.DoWork = doWork;
            this.RunWorkerCompleted = runWorkerCompleted;

            this.progressBar1.Style = ProgressBarStyle.Marquee;
        }

        public BackgroundWorkerView(int upperBound, Action<BackgroundWorker, DoWorkEventArgs> doWork, Action<BackgroundWorker, RunWorkerCompletedEventArgs> runWorkerCompleted = null)
        {            
            this.ThreadApartmentState = ApartmentState.MTA;
            InitializeComponent();
            this.Text = string.Format("{0} - 正在执行操作...", Application.ProductName);

            this.DoWork = doWork;
            this.RunWorkerCompleted = runWorkerCompleted;

            this.progressBar1.Style = ProgressBarStyle.Continuous;
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.progressBar1.Minimum = 0;
            this.progressBar1.Maximum = upperBound;
        }

        public void RunWorkerAsync()
        {
            this.backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if (this.ThreadApartmentState == ApartmentState.STA)
            {
                Exception error = null;
                Thread th = new Thread(
                    delegate()
                    {
                        try
                        {
                            this.DoWork(sender as BackgroundWorker, e);
                        }
                        catch (Exception exception)
                        {
                            error = exception;
                        }
                    });

                th.SetApartmentState(ApartmentState.STA);

                th.Start();
                th.Join();

                if (error != null)
                    throw error;
            }
            else
                this.DoWork(sender as BackgroundWorker, e);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (this.RunWorkerCompleted != null)
                this.RunWorkerCompleted(sender as BackgroundWorker, e);

            this.ExecutionResult = e;
            //这一步是设置当前窗体为对话框,这样就可以将上面的Error传出去了
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }

        private void BackgroundWorkerView_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.backgroundWorker1.IsBusy)
            {
                this.backgroundWorker1.CancelAsync();
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == this.progressBar1.Maximum)
                this.progressBar1.Style = ProgressBarStyle.Marquee;
            else
                this.progressBar1.Increment(e.ProgressPercentage);
        }

        private void BackgroundWorkerView_Load(object sender, EventArgs e)
        {
            this.RunWorkerAsync();
        }
    }
}

接下来看调用的方面:

   _dicExcelInfo = new Dictionary<string, FileTableInfo>();
            if (_selectFiles == null || _selectFiles.Count == 0)
            {
                MessageBox.Show("请选择文件!");
                return;
            }
            //文件预处理,简单的判断是否完整
            Application.DoEvents();

            bool checkFail = false;
            //这里调用该进度条窗体。此时,当里面的内容运行完,该窗体才关闭。
            BackgroundWorkerView view = new BackgroundWorkerView("正在检查选择的文件是否完整...", (worker, arg) =>
            {
                foreach (var item in _selectFiles)
                {
                    FileTableInfo zhi = ExcelHelper.CheckToExcel(item);
                    if (!_dicExcelInfo.ContainsKey(zhi.TradeDate))
                    {
                        _dicExcelInfo.Add(zhi.TradeDate, zhi);
                    }
                    else
                    {
                        if (zhi.XYFZBFlag)
                        {
                            //当前文件是信用负债文件
                            if (!_dicExcelInfo[zhi.TradeDate].XYFZBFlag)
                            {
                                //如果已经存在的当天的数据文件中,信用负债文件flag为负,则说明上一个文件不是信用负债文件
                                _dicExcelInfo[zhi.TradeDate].XYFZBFlag = zhi.XYFZBFlag;
                                _dicExcelInfo[zhi.TradeDate].XYFZBFile = zhi.XYFZBFile;
                            }
                            else
                            {
                                //导入了多个同一天的信用负债文件
                                MessageBox.Show(string.Format("选择了多个[{0}]的信用负债文件", zhi.TradeDate));
                                checkFail = true;
                                return;
                            }
                        }
                        if (zhi.JYBFlag)
                        {
                            //当前文件是交易数据文件
                            if (!_dicExcelInfo[zhi.TradeDate].JYBFlag)
                            {
                                _dicExcelInfo[zhi.TradeDate].JYBFlag = zhi.JYBFlag;
                                _dicExcelInfo[zhi.TradeDate].JYBFile = zhi.JYBFile;
                            }
                            else
                            {
                                //导入了多个同一天的交易文件
                                MessageBox.Show(string.Format("选择了多个[{0}]的交易数据文件", zhi.TradeDate));
                                //view.ExecutionResult = new RunWorkerCompletedEventArgs(false, new Exception(string.Format("选择了多个[{0}]的交易数据文件", zhi.TradeDate)), true);
                                checkFail = true;
                                return;
                            }
                        }
                    }
                }
            });
        //设置进度条窗体为显示为对话框
            var ret = view.ShowDialog();
            if (ret == System.Windows.Forms.DialogResult.OK)
            {
            //如果错误不为空,则弹出错误信息
                if (view.ExecutionResult.Error != null)
                {
                    MessageBox.Show(view.ExecutionResult.Error.Message);
                    return;
                }
            }
            if (ret == System.Windows.Forms.DialogResult.Cancel)
            {
                _dicExcelInfo = new Dictionary<string, FileTableInfo>();
                return;
            }

            if (checkFail)
            {
                //检查失败
                return;
            }

            string msg = "";
            foreach (var tradeDate in _dicExcelInfo.Keys)
            {
                FileTableInfo exInfo = _dicExcelInfo[tradeDate];
                if (exInfo.XYFZBFlag && exInfo.JYBFlag)
                {
                    continue;
                }
                else if (!exInfo.XYFZBFlag)
                {
                    msg += "日期为:" + tradeDate + " 缺失交易数据的文件  \r\n";
                }
                else if (!exInfo.JYBFlag)
                {
                    msg += "日期为:" + tradeDate + " 缺失信用账户数据的文件 \r\n";
                }
            }
            if (!string.IsNullOrEmpty(msg))
            {
                MessageBox.Show(msg);
                return;
            }
     //这一步是设置当前窗体为对话框,这一步是跨页面传值的重要的异步
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();

调用ImportData页面 的信息

    ImportData imp = new ImportData();
            if (imp.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                //选择了一批文件
                Dictionary<string, FileTableInfo> dicSelectFiles = imp.DicExcelInfo;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值