![](/img/trans.png)
[英]Why when downloading files using webclient downloadfileasync I'm getting exception on the progressBar value that it's negative value?
[英]Why when downloading images the progressBar never get to 100% and i'm getting out of range exception?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading;
namespace SatelliteImages
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ExtractImages ei = new ExtractImages();
ei.Init();
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
backgroundWorker1.RunWorkerAsync();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 0; i <= ExtractImages.imagesUrls.Count(); i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
using (var client = new WebClient())
{
client.DownloadFile(ExtractImages.imagesUrls[i], @"C:\Temp\TestingSatelliteImagesDownload\" + i + ".jpg");
worker.ReportProgress(100 * i / ExtractImages.imagesUrls.Count());
}
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label2.Text = (e.ProgressPercentage.ToString() + "%");
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
MessageBox.Show("Completed without any errors");
}
else
{
string myerr = e.Error.ToString();
}
}
}
}
为什么progressBar1达到99%并停在那里,然后到达完成的事件? 我怎样才能达到100%?
我计算reportProgress的方式和从i = 0开始的FOR循环是否正常?
如何在表单上显示新标签(例如label3)并显示剩余文件下载数量? 例如,如果在imagesUrls中有399个项目(要下载的文件),则在label3中,我希望看到每次下载文件并成功将其从399改为0或1的计数器。
现在到完成的事件时,我得到了例外:
e.Error = {“索引超出范围。必须为非负数,并且小于集合的大小。\\ r \\ n参数名称:index”}
D:\\ C-Sharp \\中的Satellite.Images.Form1.backgroundWorker1_DoWork(Object sender,DoWorkEventArgs e)的System.Collections.Generic.List`1.get_Item(Int32 index)处的System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument参数,ExceptionResource资源)中在System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)处的SatelliteImages \\ SatelliteImages \\ SatelliteImages \\ Form1.cs:第60行
在System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object参数)
我尝试的更新:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading;
namespace SatelliteImages
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ExtractImages ei = new ExtractImages();
ei.Init();
}
private async void Form1_Load(object sender, EventArgs e)
{
label1.Text = "0 %";
progressBar1.Minimum = 0;
progressBar1.Maximum = ExtractImages.imagesUrls.Count() - 1;
await DoWork();
}
private async Task DoWork()
{
for (int i = 0; i < ExtractImages.imagesUrls.Count(); i++)
{
using (var client = new WebClient())
{
await client.DownloadFileTaskAsync(ExtractImages.imagesUrls[i], @"C:\Temp\TestingSatelliteImagesDownload\" + i + ".jpg");
progressBar1.Value = i + 1;
double average = (double)(i + 1) / ExtractImages.imagesUrls.Count();
label1.Text = (Math.Round(average, 1) * 100).ToString() + " %";
}
}
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
progressBar尚未结束,它在99%处停止,我认为是99%。
label1最后显示100%,但progressBar尚未结束。
最后,我也得到了例外:
该行的Program.cs中是一个例外:
Application.Run(new Form1());
附加信息:调用的目标已引发异常。
System.Reflection.TargetInvocationException was unhandled
HResult=-2146232828
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at SatelliteImages.Program.Main() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
HResult=-2146233086
Message=Value of '399' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.
Parameter name: Value
ParamName=Value
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.ProgressBar.set_Value(Int32 value)
at SatelliteImages.Form1.<DoWork>d__2.MoveNext() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 46
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SatelliteImages.Form1.<Form1_Load>d__1.MoveNext() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 35
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state)
InnerException:
对于您的第一个,第二个和第四个问题:
您正在从0循环到两边都包括在内(0到<= count)。 这意味着您要循环计数+1次。 我不认为那是你的意图。 要解决此问题,建议您从i = 1开始。 我建议不要使用i = 0且i小于计数,因为根据您的计算,对于i = 0不会向进度栏添加任何进度。 尽管这些建议可能会有所帮助,但我强烈建议您设置progressbar.Maximum值进行计数,并在每次下载文件后仅将progressbar.Value递增1。
我怀疑您的计算是将除法结果舍入为整数。 因此,首先将i乘以100.0,然后执行除法。 像(i * 100.0)/(images_count)。
对于您的第三个要求:
请参考MSDN示例-https : //msdn.microsoft.com/zh-cn/library/t9fzsyec( v= vs.110).aspx
要解决你的答案,你需要更换<=
与<
在for循环。
现在您可以看到为什么async-await
模式很有用,该代码像任何普通代码一样流动。 检查以下简单程序是否与您的相同:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(Object sender, EventArgs e)
{
label1.Text = "0 %";
progressBar1.Minimum = 0;
progressBar1.Maximum = ExtractImages.imagesUrls.Count() - 1;
await DoWork();
}
private async Task DoWork()
{
for (int i = 0; i < ExtractImages.imagesUrls.Count(); i++)
{
using (var client = new WebClient())
{
await client.DownloadFileTaskAsync(ExtractImages.imagesUrls[i], @"C:\Temp\TestingSatelliteImagesDownload\" + i + ".jpg");
progressBar1.Value = i + 1;
double average = (double)(i + 1) / ExtractImages.imagesUrls.Count();
label1.Text = (Math.Round(average, 1) * 100).ToString() + " %";
}
}
}
}
请注意,您可以使用IProgress<int>
并将更新UI的代码与下载文件的代码解耦:
private async void Form1_Load(Object sender, EventArgs e)
{
label1.Text = "0 %";
var progress = new Progress<int>();
progress.ProgressChanged += Progress_ProgressChanged;
await DoWork(progress);
}
private void Progress_ProgressChanged(Object sender, Int32 e)
{
progressBar1.Value = e + 1;
double average = ((double)(e + 1) / (ExtractImages.imagesUrls.Count()));
label3.Text = (Math.Round(average, 1) * 100).ToString() + " %";
}
然后在下载文件之后添加:
progress.Report(i);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.