zoukankan      html  css  js  c++  java
  • 实现winfrom进度条及进度信息提示,winfrom程序假死处理

    方法一:使用线程

         功能描述:在用c#做WinFrom开发的过程中。我们经常需要用到进度条(ProgressBar)用于显示进度信息。这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口很容易假死(无法适时看到进度信息)。下面我就简单结合一个我写的例子给大家做一个介绍。

    第一步:设计界面,注意需要引用 using System.Threading;

    实现winfrom进度条及进度信息提示,winfrom程序假死处理 - china_xuhua - 许华
    控件名称分别为:
    progressBar1;label1;textBox1;button1;

    第二步:定义一个代理,用于更新ProgressBar的值(Value)及在执行方法的时候,返回方法的处理信息。
    private delegate void SetPos(int ipos,string vinfo);//代理

    第三步:进度条值更新函数(参数必须跟声明的代理参数一样)

    private void SetTextMesssage(int ipos,string vinfo)
    {
        if (this.InvokeRequired)
        {
            SetPos setpos = new SetPos(SetTextMesssage);
            this.Invoke(setpos, new object[] { ipos,vinfo });
        }
        else
        {
            this.label1.Text = ipos.ToString() + "/1000";
            this.progressBar1.Value = Convert.ToInt32(ipos);
            this.textBox1.AppendText(vinfo);
        }
    }

    第四步:函数实现

    private void button1_Click(object sender, EventArgs e)
    {
        Thread fThread = new Thread(new ThreadStart(SleepT));
        fThread.Start();
    }

    第五步:新的线程执行函数:

    private void SleepT()
    {
        for (int i = 0; i < 500; i++)
        {
            System.Threading.Thread.Sleep(10);
            SetTextMesssage(100*i/500,i.ToString()+"
    ");
        }
    }

    程序运行效果图:

    实现winfrom进度条及进度信息提示,winfrom程序假死处理 - china_xuhua - 许华
     

    方法二:控件BackgroundWorker

         功能描述:该种方法通过控件backgroundWorker1实现,进度条。进度条在一个模板窗体内。
     
    第一步:主窗体设计:
      控件名称:button1;backgroundWorker1;对backgroundWorker1控件,属性设置。

    第二步:主页面后台代码:

    using System.Threading;//引用空间名称
    
    private void button1_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync(); // 运行 backgroundWorker 组件
        ProcessForm form = new ProcessForm(this.backgroundWorker1);// 显示进度条窗体
        form.ShowDialog(this);
        form.Close();
    }
    
    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)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        for (int i = 0; i < 100; i++)
        {
            Thread.Sleep(100);
            worker.ReportProgress(i);
            if (worker.CancellationPending)  // 如果用户取消则跳出处理数据代码 
            {
                e.Cancel = true;
                break;
            }
        }
    }

    分别为button控件和backgroundWorker1控件选好事件。

    第三步:设置子窗体(及显示进度条的窗体):

    实现winfrom进度条及进度信息提示,winfrom程序假死处理 - china_xuhua - 许华
    控件名称:
    progressBar1;button1
     
    第四步:子窗体,后台代码:
    private BackgroundWorker backgroundWorker1; //ProcessForm 窗体事件(进度条窗体)
    
    public ProcessForm(BackgroundWorker backgroundWorker1)
    {
        InitializeComponent();
        this.backgroundWorker1 = backgroundWorker1;
        this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
        this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    }
    
    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //this.Close();//执行完之后,直接关闭页面
    }
    
    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.progressBar1.Value = e.ProgressPercentage;
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.CancelAsync();
        this.button1.Enabled = false;
        this.Close();
    }

    只为button选好事件,执行效果为:

    实现winfrom进度条及进度信息提示,winfrom程序假死处理 - china_xuhua - 许华

    方法三:方法二增强

         功能描述:在处理大量数据的时候,有时候方法的执行需要一定的时间,这时候往往会造成页面或程序的“假死”状态,给用户的体验度也不是很好。为了避免出现“假死”提高用户的体验度,在这里为这类型的方法加了一个进度条和一个文本框,进度条用于显示程序处理的进度,文本框用于显示在处理过程中,给与的提示。本方法主要使用了控件:backgroundWorker1;说明:本方法与上面的方法(方法二)基本类型,主要是设计和代码进行了一些修改。


     第一步:主窗体设计:

      控件名称:button1;backgroundWorker1;对backgroundWorker1控件,属性设置。

    第二步:主窗体 后台代码:

    private void button1_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync(); // 运行 backgroundWorker 组件
        ProcessForm form = new ProcessForm(this.backgroundWorker1);// 显示进度条窗体
        form.ShowDialog(this);
        form.Close();
    }
    
    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)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        for (int i = 0; i < 100; i++)
        {
            Thread.Sleep(100);
            worker.ReportProgress(i, i.ToString() + "  你好!
    "); //注意:这里向子窗体返回信息值,这里是两个值,一个用于进度条,一个用于文本框的。
            if (worker.CancellationPending)  // 如果用户取消则跳出处理数据代码 
            {
                e.Cancel = true;
                break;
            }
        }
    }

    第三步:设置子窗体(及显示进度条的窗体):

    实现winfrom进度条及进度信息提示,winfrom程序假死处理 - china_xuhua - 许华

     控件:progressBar1;textBox1;button1

    第四步:子窗体后台代码:

    private BackgroundWorker backgroundWorker1; //ProcessForm 窗体事件(进度条窗体)
    
    public ProcessForm(BackgroundWorker backgroundWorker1)
    {
        InitializeComponent();
        this.backgroundWorker1 = backgroundWorker1;
        this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
        this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    }
    
    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //this.Close();//执行完之后,直接关闭页面
    }
    
    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.progressBar1.Value = e.ProgressPercentage;
        this.textBox1.AppendText(e.UserState.ToString());//主窗体传过来的值,通过e.UserState.ToString()来接受
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.CancelAsync();
        this.button1.Enabled = false;
        this.Close();
    }

    实现的效果:

    实现winfrom进度条及进度信息提示,winfrom程序假死处理 - china_xuhua - 许华
    注意:如果在程序为执行完,就点击取消的话,很有可能会报错的,这时候,你就修改一个方法:backgroundWorker1_ProgressChanged如下:
    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.progressBar1.Value = e.ProgressPercentage;
        this.textBox1.Text += e.UserState.ToString(); //主窗体传过来的值,通过e.UserState.ToString()来接受
    }

           把这个方法,替换上边的那个方法,就可以了。


    方法四:线程与代理

    功能描述:本方法实现进度条显示,方法执行信息反馈显示。用到的技术点为 线程与代理。
         
    步骤一:添加主页面。        
      控件名称:button1;
    步骤二:主页面后台代码
    using System.Threading;//引用此命名
    
    //创建代理。
    private Form6 myProcessBar = null;//弹出的子窗体(用于显示进度条)
    private delegate bool IncreaseHandle(int nValue,string vinfo);//代理创建
    private IncreaseHandle myIncrease = null;//声明代理,用于后面的实例化代理
    private int vMax = 100;//用于实例化进度条,可以根据自己的需要,自己改变
    
    private void button1_Click(object sender, EventArgs e)
    {
        Thread thdSub = new Thread(new ThreadStart(ThreadFun));
        thdSub.Start();
    }
    private void ThreadFun()
    {
        MethodInvoker mi = new MethodInvoker(ShowProcessBar);
        this.BeginInvoke(mi);
        Thread.Sleep(100);
        object objReturn = null;
        for (int i = 0; i < vMax; i++)
        {
            objReturn = this.Invoke(this.myIncrease, new object[] { 2, i.ToString() + "
    " });
            Thread.Sleep(50);
        }
    }
    private void ShowProcessBar()
    {
        myProcessBar = new Form6(vMax);
        myIncrease = new IncreaseHandle(myProcessBar.Increase);
        myProcessBar.ShowDialog();
        myProcessBar = null;
    }

    步骤三:创建子窗体

      控件名称:progressBar1;textBox1
    步骤四:子窗体,后台代码
    public Form6(int vMax)
    {
        InitializeComponent();
        this.progressBar1.Maximum = vMax;
    }
    public bool Increase(int nValue,string nInfo)
    {
        if (nValue > 0)
        {
            if (progressBar1.Value + nValue < progressBar1.Maximum)
            {
                progressBar1.Value += nValue;
                this.textBox1.AppendText(nInfo);
                Application.DoEvents();
                progressBar1.Update();
                progressBar1.Refresh();
                this.textBox1.Update();
                this.textBox1.Refresh();
                return true;
            }
            else
            {
                progressBar1.Value = progressBar1.Maximum;
                this.textBox1.AppendText(nInfo);
                //this.Close();//执行完之后,自动关闭子窗体
                return false;
            }
        }
        return false;
    }
  • 相关阅读:
    【初码干货】使用阿里云开放搜索服务快速搭建资源搜索网站
    很认真的聊一聊程序员的自我修养
    【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系
    Supervisor 修改配置文件中的参数值,需要更新服务才能生效
    如何关闭 IntelliJ IDEA 的 Find in Path ?
    Jenkins 服务启动/关闭/重启命令,设置端口
    java.util.ConcurrentModificationException 问题处理
    MySQL 将字符串类型的小数转换为保留位数的小数类型
    Apache Tomcat 文件包含漏洞(CVE-2020-1938)
    Error EElFTPSError: Data channel transfer error (error code is 10054) MobaXterm
  • 原文地址:https://www.cnblogs.com/zhaoshujie/p/9610939.html
Copyright © 2011-2022 走看看