C# ProgressBar没有更新
我有一个progressbar,显示backgroundworker do_dowork事件返回的进度,如下所示C# ProgressBar没有更新,c#,progress-bar,backgroundworker,C#,Progress Bar,Backgroundworker,我有一个progressbar,显示backgroundworker do_dowork事件返回的进度,如下所示 if (ftpSourceFilePath.Scheme == Uri.UriSchemeFtp) { FtpWebRequest objRequest = (FtpWebRequest)FtpWebRequest.Create(ftpSourceFilePath); Network
if (ftpSourceFilePath.Scheme == Uri.UriSchemeFtp)
{
FtpWebRequest objRequest = (FtpWebRequest)FtpWebRequest.Create(ftpSourceFilePath);
NetworkCredential objCredential = new NetworkCredential(userName, password);
objRequest.Credentials = objCredential;
objRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse objResponse = (FtpWebResponse)objRequest.GetResponse();
StreamReader objReader = new StreamReader(objResponse.GetResponseStream());
int len = 0;
int iProgressPercentage = 0;
FileStream objFS = new FileStream((cd+"\\VolareUpdate.rar"), FileMode.Create, FileAccess.Write, FileShare.Read);
while ((len = objReader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
{
objFS.Write(buffer, 0, len);
iRunningByteTotal += len;
double dIndex = (double)(iRunningByteTotal);
double dTotal = (double)buffer.Length;
double dProgressPercentage = (dIndex / dTotal);
iProgressPercentage = (int)(dProgressPercentage);
if (iProgressPercentage > 100)
{
iProgressPercentage = 100;
}
bw.ReportProgress(iProgressPercentage);
}
}
delegate void SetProgressBar(int percentage, bool logic);
private void SetProgress(int percentage, bool logic)
{
if (progressBar.InvokeRequired)
{
SetProgressBar d = new SetProgressBar(SetProgress);
this.Invoke(d, new object[] { percentage, logic });
}
else
{
progressBar.Style = ProgressBarStyle.Blocks;
progressBar.Value = percentage;
progressBar.Text = percentage.ToString() + "%";
}
}
但是,我的progressbar不会更新。在搜索时,我被告知UI线程被阻塞,然后我认为将进度传递到循环之外可能会奏效。然后我换成这个
if (ftpSourceFilePath.Scheme == Uri.UriSchemeFtp)
{
FtpWebRequest objRequest = (FtpWebRequest)FtpWebRequest.Create(ftpSourceFilePath);
NetworkCredential objCredential = new NetworkCredential(userName, password);
objRequest.Credentials = objCredential;
objRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse objResponse = (FtpWebResponse)objRequest.GetResponse();
StreamReader objReader = new StreamReader(objResponse.GetResponseStream());
int len = 0;
int iProgressPercentage = 0;
FileStream objFS = new FileStream((cd+"\\VolareUpdate.rar"), FileMode.Create, FileAccess.Write, FileShare.Read);
while ((len = objReader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
{
objFS.Write(buffer, 0, len);
iRunningByteTotal += len;
double dIndex = (double)(iRunningByteTotal);
double dTotal = (double)buffer.Length;
double dProgressPercentage = (dIndex / dTotal);
iProgressPercentage = (int)(dProgressPercentage);
if (iProgressPercentage > 100)
{
iProgressPercentage = 100;
}
// System.Threading.Thread.Sleep(2000);
iProgressPercentage++;
// SetText("F", true);
}
bw.ReportProgress(iProgressPercentage);
progressBar.Refresh();
}
但是还是没有帮助。当我在workerprogresschanged事件中放置断点时,它会显示progressbar.value,但不会更新。我尝试了progressbar.update0,我还尝试了在循环中休眠线程一段时间,但仍然没有帮助。如果您有任何建议/帮助,我们将不胜感激。没错,您不能通过dowork方法访问UI线程。您需要使用progresschanged事件
看一看,我想你错过了一个对Application.DoEvents的调用 在长时间运行的任务(如循环)中,如果要对UI进行任何更改,则应调用
Application.DoEvents()
这将反映对用户界面所做的更改。感谢您的回复。我使用下面的委托方法实现了这一点
if (ftpSourceFilePath.Scheme == Uri.UriSchemeFtp)
{
FtpWebRequest objRequest = (FtpWebRequest)FtpWebRequest.Create(ftpSourceFilePath);
NetworkCredential objCredential = new NetworkCredential(userName, password);
objRequest.Credentials = objCredential;
objRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse objResponse = (FtpWebResponse)objRequest.GetResponse();
StreamReader objReader = new StreamReader(objResponse.GetResponseStream());
int len = 0;
int iProgressPercentage = 0;
FileStream objFS = new FileStream((cd+"\\VolareUpdate.rar"), FileMode.Create, FileAccess.Write, FileShare.Read);
while ((len = objReader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
{
objFS.Write(buffer, 0, len);
iRunningByteTotal += len;
double dIndex = (double)(iRunningByteTotal);
double dTotal = (double)buffer.Length;
double dProgressPercentage = (dIndex / dTotal);
iProgressPercentage = (int)(dProgressPercentage);
if (iProgressPercentage > 100)
{
iProgressPercentage = 100;
}
bw.ReportProgress(iProgressPercentage);
}
}
delegate void SetProgressBar(int percentage, bool logic);
private void SetProgress(int percentage, bool logic)
{
if (progressBar.InvokeRequired)
{
SetProgressBar d = new SetProgressBar(SetProgress);
this.Invoke(d, new object[] { percentage, logic });
}
else
{
progressBar.Style = ProgressBarStyle.Blocks;
progressBar.Value = percentage;
progressBar.Text = percentage.ToString() + "%";
}
}
还有我的嫁妆活动
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while ((len = objReader.BaseStream.Read(buffer, 0, buffer.Length)) != 0)
{
.....
.......
int iProgressPercentage = (int)(dProgressPercentage * 100);
bw.ReportProgress(iProgressPercentage);
}
}
在my Progress changed事件中,触发上面的委托方法
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
SetProgress(e.ProgressPercentage, true);
}
这非常好,没有问题……感谢您的贡献。您确定您对objReader.BaseStream.Readbuffer的初始调用为0,buffer.Length实际返回的值不是0吗?若缓冲区最初是一个空数组,我可以看到这可能会导致意外行为。可能需要一点调试来证明发生了什么。当计算小数点时,您的百分比是0.3吗?就是这样,需要乘以100。将0.3转换为int将取得0的进步。你也在处理backgroundworker的进度事件来更新bar.Yah。好的,请参阅上面的更新。你可以从那里开始。它读取并返回文件。我的问题是'bw.reportProgressipProgressPercentage`没有,先生。我的百分比实际上是一个数字。考虑到我正在下载的文件是20mb,dindex在某一点上比total大。这就是为什么我把if放在下面,使它成为一个大于100的整体100。也像我说的。我削减了progresbar.value,它确实是一个进步的数字,上升到100。但是它不会更新进度。您的进度条是否在某个时间内没有更新atall或更新并在其间停止?我使用它来接收进度,并且值显示正确。但是,进度条不显示该值。它根本不更新。@NuruSalihu:因此它确认您的UI没有响应/反映更改。下载文件时窗口是否冻结?