码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2018-09-08 23:37:19      阅读:411      评论:0      收藏:0      [点我收藏+]

标签:ogr   color   syn   als   时间   require   label   调用   handle   

方法一:使用线程

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

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

技术分享图片
控件名称分别为:
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()+"\r\n");
    }
}

程序运行效果图:

技术分享图片
 

方法二:控件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控件选好事件。

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

技术分享图片
控件名称:
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选好事件,执行效果为:

技术分享图片

方法三:方法二增强

     功能描述:在处理大量数据的时候,有时候方法的执行需要一定的时间,这时候往往会造成页面或程序的“假死”状态,给用户的体验度也不是很好。为了避免出现“假死”提高用户的体验度,在这里为这类型的方法加了一个进度条和一个文本框,进度条用于显示程序处理的进度,文本框用于显示在处理过程中,给与的提示。本方法主要使用了控件: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() + "  你好!\r\n"); //注意:这里向子窗体返回信息值,这里是两个值,一个用于进度条,一个用于文本框的。
        if (worker.CancellationPending)  // 如果用户取消则跳出处理数据代码 
        {
            e.Cancel = true;
            break;
        }
    }
}

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

技术分享图片

 控件: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();
}

实现的效果:

技术分享图片
注意:如果在程序为执行完,就点击取消的话,很有可能会报错的,这时候,你就修改一个方法: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() + "\r\n" });
        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;
}

 

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

标签:ogr   color   syn   als   时间   require   label   调用   handle   

原文地址:https://www.cnblogs.com/zhaoshujie/p/9610939.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!