using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;namespace ProgressBarDemo
{
public partial class Form1 : Form
{
private bool IsFinsh = false;
private int index = 0;
private byte[] buffer; public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
this.progressBar1.Visible = false;
this.timer1.Enabled = false;
} private void timer1_Tick(object sender, EventArgs e)
{
this.progressBar1.Value = index;
} private void btnCopy_Click(object sender, EventArgs e)
{
string fileName = "";
string endName = ""; OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
fileName = ofd.FileName;
endName = ofd.SafeFileName;
}
else
{
return;
} this.progressBar1.Visible = true;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
int size = (int)fs.Length;
this.progressBar1.Maximum = size;
this.progressBar1.Minimum = 0; FileStream fsWriter = new FileStream("c:\\" + endName, FileMode.Append, FileAccess.Write); buffer =new byte [1024];
while (fs.Read (buffer ,0,1024)!=0)
{
this.timer1.Enabled = true;
index += buffer.Length;
fsWriter.Write(buffer, 0, 1024);
}
fs.Close();
fsWriter.Close();
this.IsFinsh = true;
this.timer1.Enabled = false;
}
}
}
请问为什么tiem_tick方法没有执行,导致progressbar.value的值始终为0?
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;namespace ProgressBarDemo
{
public partial class Form1 : Form
{
private bool IsFinsh = false;
private int index = 0;
private byte[] buffer; public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
this.progressBar1.Visible = false;
this.timer1.Enabled = false;
} private void timer1_Tick(object sender, EventArgs e)
{
this.progressBar1.Value = index;
} private void btnCopy_Click(object sender, EventArgs e)
{
string fileName = "";
string endName = ""; OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
fileName = ofd.FileName;
endName = ofd.SafeFileName;
}
else
{
return;
} this.progressBar1.Visible = true;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
int size = (int)fs.Length;
this.progressBar1.Maximum = size;
this.progressBar1.Minimum = 0; FileStream fsWriter = new FileStream("c:\\" + endName, FileMode.Append, FileAccess.Write); buffer =new byte [1024];
while (fs.Read (buffer ,0,1024)!=0)
{
this.timer1.Enabled = true;
index += buffer.Length;
fsWriter.Write(buffer, 0, 1024);
}
fs.Close();
fsWriter.Close();
this.IsFinsh = true;
this.timer1.Enabled = false;
}
}
}
请问为什么tiem_tick方法没有执行,导致progressbar.value的值始终为0?
每次执行的时候先判断是否为true,如果为true就不执行这句
你的界面没有刷新.
如果只需刷新progressbar,则progressbar.refresh();就行了.
整个画面刷新,this.refresh();你有没有设置progressbar的step及max
通常情况下,step+=1;progressbar.value=step;这样的.没有区分大小写.自己修正.
while (fs.Read (buffer ,0,1024)!=0)
{
if(!this.timer1.Enabled)this.timer1.Enabled = true;
Application.DoEvents();
index += buffer.Length;
fsWriter.Write(buffer, 0, 1024);
}
难道你们都看见
buffer =new byte [1024];
while (fs.Read (buffer ,0,1024)!=0)
{
this.timer1.Enabled = true;
index += buffer.Length;
fsWriter.Write(buffer, 0, 1024);
}
还有我调试过,确实没有执行tick方法,不知道为什么?
Application.DoEvents();
这个方法在此处做什么用?
为什么没有执行这个方法就不行了?
记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了Application.DoEvents(),今天看到了关于这方面的一些文章,知道我以前有些用法是不当的,有些地方需要慎用Application.DoEvents()。首先我们先看看在循环比较大的程序中,它的作用还是不错的,起到了一个实时响应的效果,例如:for (int q = 0; q < 1000000; q++) { textBox1.Text = q.ToString(); Application.DoEvents();//实时响应文本框中的值 }如果没有加上 DoEvents的话,由于循环时间会比较久就会出现假死的状态,而且程序不能处理其他的事件。而如果加上DoEvents的话就会对文本框的值实时响应,给用户带来较好的用户体验,可是DoEvents也带来了效率上的问题,处理同样的一个事件调用了DoEvents后效率降低了好几倍,这也是为什么要慎用的原因了。下面是我做的一个测试: private void button1_Click(object sender, EventArgs e) { expendTime.start(); for (int q = 0; q < 100000; q++) { textBox1.Text = q.ToString(); Application.DoEvents(); } label2.Text = expendTime.ComputerTime();//计算耗时 } private void button2_Click(object sender, EventArgs e) { expendTime.start(); for (int q = 0; q < 100000; q++) { textBox2.Text = q.ToString(); } label3.Text = expendTime.ComputerTime();//计算耗时 }执行耗时对比:从较大数据的循环中可以看出效率是很低的,所以如果能不调用DoEvents就尽量不用。也可以通过别的方法来处理的,例如多线程异步调用等。MSDN中的定义:当运行 Windows 窗体时,它将创建新窗体,然后该窗体等待处理事件。该窗体在每次处理事件时,均将处理与该事件关联的所有代码。所有其他事件在队列中等待。在代码处理事件时,应用程序并不响应。例如,当将另一窗口拖到该窗口前面时,该窗口不重新绘制。如果在代码中调用 DoEvents,则您的应用程序可以处理其他事件。例如,如果您有向 ListBox 添加数据的窗体,并将 DoEvents 添加到代码中,那么当将另一窗口拖到您的窗体上时,该窗体将重新绘制。如果从代码中移除 DoEvents,那么在按钮的单击事件处理程序执行结束以前,您的窗体不会重新绘制。 通常,您在循环中使用该方法来处理消息。
//系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了
//Application.DoEvents(),今天看到了关于这方面的一些文章,知道我以前有些用法是不当的,有些地方
//需要慎用Application.DoEvents()。//首先我们先看看在循环比较大的程序中,它的作用还是不错的,起到了一个实时响应的效果,例如:for (int q = 0; q < 1000000; q++) { textBox1.Text = q.ToString(); Application.DoEvents();//实时响应文本框中的值 }//如果没有加上 DoEvents的话,由于循环时间会比较久就会出现假死的状态,而且程序不能处理其他的事
//件。而如果加上DoEvents的话就会对文本框的值实时响应,给用户带来较好的用户体验,可是DoEvents也
//带来了效率上的问题,处理同样的一个事件调用了DoEvents后效率降低了好几倍,这也是为什么要慎用的原
//因了。下面是我做的一个测试: private void button1_Click(object sender, EventArgs e) { expendTime.start(); for (int q = 0; q < 100000; q++) { textBox1.Text = q.ToString(); Application.DoEvents(); } label2.Text = expendTime.ComputerTime();//计算耗时 } private void button2_Click(object sender, EventArgs e) { expendTime.start(); for (int q = 0; q < 100000; q++) { textBox2.Text = q.ToString(); } label3.Text = expendTime.ComputerTime();//计算耗时 }//执行耗时对比:
/*
从较大数据的循环中可以看出效率是很低的,所以如果能不调用DoEvents就尽量不用。
也可以通过别的方法来处理的,例如多线程异步调用等。MSDN中的定义:当运行 Windows 窗体时,它将创建新窗体,然后该窗体等待处理事件。该窗体在每次处理事件时,
均将处理与该事件关联的所有代码。所有其他事件在队列中等待。在代码处理事件时,应用程序并不响应。
例如,当将另一窗口拖到该窗口前面时,该窗口不重新绘制。如果在代码中调用 DoEvents,
则您的应用程序可以处理其他事件。例如,如果您有向 ListBox 添加数据的窗体,并将 DoEvents 添加到代码中,那么当将另一窗口拖到您的窗体上时,该窗体将重新绘制。
如果从代码中移除 DoEvents,那么在按钮的单击事件处理程序执行结束以前,
您的窗体不会重新绘制。 通常,您在循环中使用该方法来处理消息。*/
this.timer1.Enabled = false;
timer1.Tick += new System.EventHandler(this.timer1_Tick);
private void btnTest_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10000; i++)
{
this.txtMessage.Text = i.ToString();
}
}
以上代码的运行结果:消息框内只显示9999,并且有较长的等待时间;为了实时显示1--9999,我们做了如下处理
private void btnTest_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10000; i++)
{
this.txtMessage.Text = i.ToString();
Application.DoEvents();//实时响应对消息框的处理
}
} 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/KernelHacker/archive/2007/04/23/1575327.aspx
void UpdateMyBar(int iMyBar)
{
if (this.progressBar1.Value != this.progressBar1.Maximum)
{
if (this.progressBar1.InvokeRequired)
{
UpdateBar pb = new UpdateBar(UpdateMyBar);
IAsyncResult pbaResult = this.progressBar1.BeginInvoke(pb, new object[] { iMyBar});
try { pb.EndInvoke(pbaResult); }
catch { }
}
else { this.progressBar1.Value++; }
}
}
参考
doevents顾名思义了