我有一个进度条,即显示backgroundworker do_dowork事件返回的进度,如下所示。
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);
}
}
但是,我的进度条不会更新。在搜索时,我被告知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.update(0,我也尝试在循环中暂停一段时间仍然没有帮助。请任何建议/帮助将不胜感激。
答案 0 :(得分:0)
没错,您无法从dowork()方法访问UI Thread。您需要使用progresschanged事件。
查看http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo和C#, Updating a Progress Bar Using Background Worker From a Different Class
答案 1 :(得分:0)
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
答案 2 :(得分:0)
我认为你错过了对Application.DoEvents()的调用
如果您想要进行任何UI更改,在循环等长时间运行的任务中,您应该调用
Application.DoEvents()
这将反映对UI的更改。
答案 3 :(得分:0)
感谢您的回复。我使用如下的委托方法实现了这一点。
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() + "%";
}
}
我的dowork活动
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);
}
}
在我的Progress更改事件中,触发上面的委托方法。
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
SetProgress(e.ProgressPercentage, true);
}
这没有问题,效果很好...感谢您的所有贡献。