C#开发WinForm进度条开发

12 篇文章 6 订阅

C#开发WinForm进度条开发

前言

开发windows窗体组件,由于业务复杂需要进度条,使用ProgressBar控件。
winForm弹出窗口有两种方式:非模态窗口方式和模态窗口方式。
Show():非模态窗口方式(可以跟其他界面自由切换,而且不阻塞代码)
ShowDialog():模态窗口(必须关闭了该窗口,后面的代码才会执行,并且不能跟其他界面自由切换)。
这里面的进度条和我们开发web前端还不一样。我们知道js里,当我们弹出个进度框后,后面代码是可以执行的。在这里不行。
如果我们想用模态方式弹出框,同时还想执行后面代码。这种想法是实现不了了。只有一种办法(至少我这么认为)。将逻辑部份和组件放在一起,同时使用线程去更新UI。

实现

这里以下载文件,同时显示进度条的功能为例。

新建一个windows窗体组件,名字为DownLoadingForm
LabelProgressBar组件到窗体里。如下

在这里插入图片描述

去掉头部的按钮(包括最大/最小/关闭按钮):将窗体的FormBorderStyle设为None
代码如下:

using DongliCAD.utils;
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 DongliCAD.component.common
{
    public partial class DownLoadingForm : Form
    {
        private string downUrl;
        private string savePath;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="downUrl">下载url</param>
        /// <param name="savePath">本地保存路径</param>
        public DownLoadingForm(string downUrl, string savePath)
        {
            this.downUrl = downUrl;
            this.savePath = savePath;
            InitializeComponent();
        }

        /// <summary>
        /// 启动线程
        /// </summary>
        private void startThread()
        {
            //重新开一个线程用于更新UI
            ThreadStart ts = new ThreadStart(startTime);
            Thread thread = new Thread(ts);
            thread.Name = "startTime";
            thread.Start();
        }

        private System.Timers.Timer aTimer;
        /// <summary>
        /// 定时器
        /// </summary>
        private void startTime()
        {
            aTimer = new System.Timers.Timer();
            aTimer.Elapsed += new System.Timers.ElapsedEventHandler(aTimer_Elapsed);
            // 设置引发时间的时间间隔 此处设置为1秒
            aTimer.Interval = 1000;
            aTimer.Enabled = true;

            //HttpDownUtil是我的下载类。
            string resultPath = HttpDownUtil.HttpDownloadFile(downUrl, savePath);
            if (!string.IsNullOrEmpty(resultPath))
            {
                CloseTime();
            }
        }

        private delegate void SetProgressBarC(string str);
        private void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            progressBar.Invoke(new EventHandler(delegate {
                if (null != progressBar)
                {
                    int currentValue = progressBar.Value;
                    currentValue += NumberUtil.getRandNum();
                    currentValue = currentValue >= 98 ? 98 : currentValue;
                    progressBar.Value = currentValue;
                    progressLbl.Text = "下载CAD文件进度:" + currentValue + "%";
                    if (progressBar.Value >= 100)
                    {
                        if(null != aTimer) {
                            aTimer.Enabled = false;
                            aTimer.Close();
                        }
                    }
                }
            }
            ));
        }

        public void CloseTime()
        {
            if (null != aTimer)
            {
                aTimer.Enabled = false;
                aTimer.Close();
            }
            progressBar.Invoke(new EventHandler(delegate {
                if (null != progressBar)
                {
                    int currentValue = 100;
                    progressBar.Value = currentValue;
                    progressLbl.Text = "下载CAD文件进度:" + currentValue + "%";
                    Thread.Sleep(1000);
                    this.Close();
                }
            }
            ));
        }

        private void DownLoadingForm_Load(object sender, EventArgs e)
        {
            //组件初始化完成,启动线程
            startThread();
        }
    }
}

其中注意下载方法HttpDownUtil.HttpDownloadFile也必需放在新线程里执行。这里我只用了假的进度条,真实的太复杂

HttpDownUtil.csHttpDownloadFile方法:

/// <summary>
        /// 同步下载
        /// Http下载文件
        /// </summary>
        public static string HttpDownloadFile(string url, string path)
        {
            // 设置参数
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            if (GlobalData.Authorization.Length > 0)
            {
                request.Headers.Add("Authorization", GlobalData.Authorization);
            }
            //发送请求并获取相应回应数据
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            //直到request.GetResponse()程序才开始向目标网页发送Post请求
            Stream responseStream = response.GetResponseStream();
            //创建本地文件写入流
            Stream stream = new FileStream(path, FileMode.Create);
            byte[] bArr = new byte[1024];
            int size = responseStream.Read(bArr, 0, (int)bArr.Length);
            while (size > 0)
            {
                stream.Write(bArr, 0, size);
                size = responseStream.Read(bArr, 0, (int)bArr.Length);
            }
            stream.Close();
            responseStream.Close();
            return path;
        }

结果

结果如下:
在这里插入图片描述


补充

上面的下载是同步下载,如果在实时显示下载进度需要异常下载。下面代码是实时显示下载进度的代码。

/// <summary>
    /// 下载请求信息
    /// </summary>
    public class DownloadTmp
    {
        /// <summary>
        /// 文件名
        /// </summary>
        public string fileName;
        /// <summary>
        /// 下载路径
        /// </summary>
        public string filePath;
        /// <summary>
        /// 下载进度回调
        /// </summary>
        public Action<int> loadingCallback;
        /// <summary>
        /// 完成回调
        /// </summary>
        public Action succeedCallback;
        /// <summary>
        /// 失败回调
        /// </summary>
        public Action failedCallback;
        /// <summary>
        /// webRequest
        /// </summary>
        public HttpWebRequest webRequest;

        public long AllContentLength;

        public long currentContentLength;
    }

using DongliCAD.utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DongliCAD.component.common
{
    public partial class DownLoadingForm : Form
    {
        private string downUrl;
        private string savePath;
        private DownloadTmp downloadTmp;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="downUrl">下载url</param>
        /// <param name="savePath">本地保存路径</param>
        public DownLoadingForm(string downUrl, string savePath)
        {
            this.downUrl = downUrl;
            this.savePath = savePath;
            InitializeComponent();
        }

        /// <summary>
        /// 启动线程
        /// </summary>
        private void startThread()
        {
            downloadTmp = new DownloadTmp();
            downloadTmp.filePath = savePath;
            HttpDownloadZip(downUrl, ref downloadTmp);
            //HttpDownUtil.HttpDownloadFile("http://192.168.1.243:85/api/files/download/516610289672650758", savePath);
        }

  
        private void DownLoadingForm_Load(object sender, EventArgs e)
        {
            //组件初始化完成,启动线程
            startThread();
        }

        private void updateProgressBar(long allContentLength, long currentContentLength)
        {
            Debug.Write("allContentLength: " + allContentLength + ",currentContentLength: " + currentContentLength);
            progressBar.Invoke(new EventHandler(delegate {
                if (null != progressBar)
                {
                    int step = Convert.ToInt32(currentContentLength * 100 / allContentLength);
                    progressBar.Value = step;
                    progressLbl.Text = "下载CAD文件进度:" + step + "%";
                }
            }
            ));
        }

        /// <summary>
        /// 异步回调
        /// </summary>
        /// <param name="result">Result.</param>
        private void BeginResponseCallback(IAsyncResult result)
        {
            DownloadTmp downloadInfo = (DownloadTmp)result.AsyncState;
            HttpWebRequest Request = downloadInfo.webRequest;
            HttpWebResponse Response = (HttpWebResponse)Request.EndGetResponse(result);

            if (Response.StatusCode == HttpStatusCode.OK || Response.StatusCode == HttpStatusCode.Created)
            {
                string filePath = downloadInfo.filePath;


                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
                //FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
                FileStream fs = File.OpenWrite(filePath);

                Stream stream = Response.GetResponseStream();

                int count = 0;
                int num = 0;
                long AllContentLength = Response.ContentLength;
                long currentContentLength = 0;
                if (Response.ContentLength > 0)
                {
                    var buffer = new byte[2048 * 100];
                    do
                    {
                        num++;
                        count = stream.Read(buffer, 0, buffer.Length);
                        currentContentLength += count;

                        updateProgressBar(AllContentLength, currentContentLength);
                        fs.Write(buffer, 0, count);
                        if (downloadInfo.loadingCallback != null)
                        {
                            float pro = (float)fs.Length / Response.ContentLength * 100;
                            downloadInfo.loadingCallback((int)pro);
                        }
                    } while (count > 0);
                }
                fs.Close();
                Response.Close();
                if (downloadInfo.succeedCallback != null)
                {
                    downloadInfo.succeedCallback();
                }
                progressBar.Invoke(new EventHandler(delegate {
                    this.Close();
                    this.DialogResult = DialogResult.OK;
                }));
            }
            else
            {
                Response.Close();
                if (downloadInfo.failedCallback != null)
                {
                    downloadInfo.failedCallback();
                }
                progressBar.Invoke(new EventHandler(delegate {
                    this.Close();
                    this.DialogResult = DialogResult.Cancel;
                }));
            }
        }

        /// <summary>
        /// 下载文件,异步
        /// </summary>
        /// <param name="URL">下载路径</param>
        /// <param name="downloadPath">文件下载路径</param>
        /// <returns></returns>
        public void HttpDownloadZip(string URL, ref DownloadTmp downloadInfo)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
            if (GlobalData.Authorization.Length > 0)
            {
                request.Headers.Add("Authorization", GlobalData.Authorization);
            }
            downloadInfo.webRequest = request;
            request.BeginGetResponse(BeginResponseCallback, downloadInfo);
        }
    }
}

---------------补充2019-01-22-----------------

BackgroundWorker方式

使用BackgroundWorker做成一个上传进度条,外部传入进度值显示,对,就是和你心里想的一样的进度条。

  1. 拖拽一个BackgroundWorker到需要弹出进度条框的窗体上。
    添加代码如下
private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {

            }
            else
            {

            }
        }

        private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            startAssembly();
        }

        private void startAssembly()
        {
            //导出pdf
            this.backgroundWorker1.ReportProgress(20, "正在导出PDF...(1/6)");
            this.xExportPDF(this);
            Boolean result = false;
            this.backgroundWorker1.ReportProgress(30, "正在签出...(2/6)");
            result = this.CheckOut();
            this.backgroundWorker1.ReportProgress(40, "正在保存图纸...(3/6)");
            result = this.DoSaveTitleWBaseInfo();
            if (!result)
            {
                return;
            }
            this.SaveWorkspaceCadInfoVo();
            this.backgroundWorker1.ReportProgress(60, "正在保存BOM...(4/6)");
            result = this.SaveBom();
            if (!result)
            {
                return;
            }
            this.backgroundWorker1.ReportProgress(80, "正在签入...(5/6)");
            this.CheckIn();
            closeTimeout();
            this.backgroundWorker1.ReportProgress(100, "保存成功...(6/6)");
        }
  1. 新建一个进度条窗体,包括一个ProgressBar和一个显示文件Label,代码如下
public partial class UploadLoadingWorkerForm : Form
    {
        private BackgroundWorker backgroundWorker;
        /// <summary>
        /// 
        /// </summary>
        public UploadLoadingWorkerForm(BackgroundWorker backgroundWorker)
        {
            InitializeComponent();
            GlobalData.SetAutoScaleMode(this);
            this.backgroundWorker = backgroundWorker;
            this.backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            this.backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();//执行完之后,直接关闭页面
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar.Value = e.ProgressPercentage;
            this.progressLbl.Text = e.UserState.ToString();
        }

最主要的是backgroundWorker1_ProgressChanged事件处理函数,外部通过 this.backgroundWorker1.ReportProgress(30, “正在签出…(2/6)”);传值,事件处理函数负责接收并显示进度和文本。

  1. 弹出进度条
UploadLoadingWorkerForm uploadLoadingForm = new UploadLoadingWorkerForm ();
 this.backgroundWorker1.RunWorkerAsync(); // 运行 backgroundWorker 组件
 uploadLoadingForm = new UploadLoadingWorkerForm(this.backgroundWorker1);
### 回答1: 这个企业Spark案例是关于出租车轨迹分析的。通过使用Spark技术,可以对出租车的轨迹数据进行处理和分析,从而得出有关出租车行驶路线、速度、拥堵情况等方面的信息。这些信息可以帮助企业优化出租车调度和路线规划,提高出租车服务的效率和质量。同时,这个案例也展示了Spark在大数据处理和分析方面的强大能力,为企业提供了更高效、更准确的数据分析解决方案。 ### 回答2: 出租车轨迹分析是一种典型的企业Spark案例,它运用大数据技术对城市出租车运行轨迹进行分析,旨在更好地了解城市交通流向、拥堵情况、客流量等,为城市规划和交通管理提供决策支持。 该系统的数据来源主要是出租车GPS定位数据和交通系统数据,运用Spark技术将海量数据进行处理和分析,获取有价值的信息。具体来说,该系统主要分为三个模块:数据采集、数据处理和数据展示。 在数据采集方面,系统需要获取城市出租车的实时位置信息,需要对出租车进行GPS定位和追踪,将出租车行驶的轨迹数据实时传输至数据处理模块,实现数据的实时收集和传输。 在数据处理方面,系统采用Spark Streaming技术实现实时流处理,对实时采集到的轨迹数据进行处理,筛选出有用的信息,如城市交通流向、热门拥堵路段、客流高峰时段等,并将这些信息实时传输到数据展示模块。 在数据展示方面,系统采用可视化技术,将通过实时处理得到的信息展示在地图上,包括城市交通热力图、热门拥堵点、客流高峰路段等,使用户可以直观地了解城市交通情况,帮助决策者提高交通效率,创造更好的城市交通生活。 总之,企业Spark案例——出租车轨迹分析,运用大数据技术提升城市交通管理水平,为城市交通建设和规划提供有力支持,具有很大的价值和应用前景。 ### 回答3: 出租车轨迹分析是一项十分重要的技术,对于城市交通规划和出租车业务管理,以及出租车司机日常工作都有着重大的意义。通过对出租车轨迹数据进行分析,可以获得很多有用的信息,比如出租车的行驶模式、常用行驶路线、交通拥堵情况等,这些信息可以帮助出租车公司优化出租车调度、提高业务效率,提高乘客满意度。 企业 Spark案例——出租车轨迹分析,利用 Spark 进行数据处理和分析,实现对大规模出租车轨迹数据的实时处理和可视化,为出租车公司和城市交通规划部门提供了非常有价值的技术支持。 出租车轨迹分析的具体流程如下: 1、数据采集:利用 GPS 定位技术,对出租车进行实时定位,将出租车的实时位置信息记录下来,形成出租车轨迹数据。 2、数据预处理:对采集到的出租车轨迹数据进行清洗和预处理,去除异常点和误差数据,形成完整的轨迹数据。 3、数据存储:将预处理后的轨迹数据存储到 Hadoop 集群中,利用 Spark 进行数据处理和分析。 4、数据分析:通过 Spark 进行实时的数据处理和分析,对出租车轨迹数据进行聚类分析、热度分析等多种分析方法,计算出不同时间段和不同区域内的出租车数量、出租车行驶速度、常用行驶路线等信息。 5、数据可视化:将分析结果可视化展示,利用地图等工具将轨迹数据绘制成热力图、聚类图等形式,为城市交通规划部门、出租车公司和出租车司机提供有用的参考信息。 通过企业 Spark案例 —— 出租车轨迹分析,可以实现对大规模出租车轨迹数据的实时处理和可视化展示,为城市交通规划和出租车业务管理提供了非常有用的技术支持。随着城市交通的发展和数据采集技术的不断进步,出租车轨迹分析技术将越来越受到重视,企业需要积极采用这一技术,将其应用于出租车业务管理和城市交通规划中,促进城市交通的发展和出租车业务的提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值