2017-03-07 65 views
0
private void downloadFile(Int32 fileNr) 
     { 
      FileStream writer = null; 
      m_currentFileSize = 0; 
      fireEventFromBgw(Event.FileDownloadAttempting); 

      FileInfo file = this.Files[fileNr]; 
      FileInfo fileFirstDateTime = this.Files[0]; 
      FileInfo fileLastDateTime = this.Files[19]; 
      Int64 size = 0; 

      Byte[] readBytes = new Byte[this.PackageSize]; 
      Int32 currentPackageSize; 
      System.Diagnostics.Stopwatch speedTimer = new System.Diagnostics.Stopwatch(); 
      Int32 readings = 0; 
      Exception exc = null; 
      writer = LocalDirectorySettings(file); 
      HttpWebRequest webReq; 
      HttpWebResponse webResp = null; 

      try 
      { 
       webReq = (HttpWebRequest)System.Net.WebRequest.Create(this.Files[fileNr].Path); 
       webResp = (HttpWebResponse)webReq.GetResponse(); 

       size = webResp.ContentLength; 
      } 
      catch (Exception ex) { exc = ex; } 

      m_currentFileSize = size; 
      fireEventFromBgw(Event.FileDownloadStarted); 

      if (exc != null) 
      { 
       bgwDownloader.ReportProgress((Int32)InvokeType.FileDownloadFailedRaiser, exc); 
      } 
      else 
      { 
       m_currentFileProgress = 0; 
       while (m_currentFileProgress < size && !bgwDownloader.CancellationPending) 
       { 
        while (this.IsPaused) { System.Threading.Thread.Sleep(100); } 

        speedTimer.Start(); 

        currentPackageSize = webResp.GetResponseStream().Read(readBytes, 0, this.PackageSize); 

        m_currentFileProgress += currentPackageSize; 
        m_totalProgress += currentPackageSize; 
        fireEventFromBgw(Event.ProgressChanged); 
        try 
        { 
         writer.Write(readBytes, 0, currentPackageSize); 
        } 
        catch(Exception eee) 
        { 
         string myeee = eee.ToString(); 
        } 
        readings += 1; 

        if (readings >= this.StopWatchCyclesAmount) 
        { 
         m_currentSpeed = (Int32)(this.PackageSize * StopWatchCyclesAmount * 1000/(speedTimer.ElapsedMilliseconds + 1)); 
         speedTimer.Reset(); 
         readings = 0; 
        } 
       } 

       speedTimer.Stop(); 
       writer.Close(); 
       webResp.Close(); 
       if (!bgwDownloader.CancellationPending) { fireEventFromBgw(Event.FileDownloadSucceeded); } 
      } 
      fireEventFromBgw(Event.FileDownloadStopped); 
     } 

的bgwDownloader如何在文件下载完成后知道如何使用httpwebrequest和webresponse?

private BackgroundWorker bgwDownloader = new BackgroundWorker(); 

的DoWork的事件

private void bgwDownloader_DoWork(object sender, DoWorkEventArgs e) 
     { 
      Int32 fileNr = 0; 
      countFilesNames = 0; 

      if (this.SupportsProgress) { calculateFilesSize(); } 

      if (!Directory.Exists(this.LocalDirectory)) { Directory.CreateDirectory(this.LocalDirectory); } 

      while (fileNr < this.Files.Count && !bgwDownloader.CancellationPending) 
      { 
       m_fileNr = fileNr; 
       downloadFile(fileNr); 

       if (bgwDownloader.CancellationPending) 
       { 
        fireEventFromBgw(Event.DeletingFilesAfterCancel); 
        cleanUpFiles(this.DeleteCompletedFilesAfterCancel ? 0 : m_fileNr, this.DeleteCompletedFilesAfterCancel ? m_fileNr + 1 : 1); 
       } 
       else 
       { 
        fileNr += 1; 
       } 
      } 
     } 

在BackgroundWorker的完成的事件,它变得只有当所有的文件下载完成完成的事件。

但我需要为每个文件下载完成创建事件。 这个问题如果我不需要使用backgroundworker或httpwebrequest webresponde以某种方式做到这一点?如何 ?

如果需要的话,我会上传整个班级,有点长。

更新

这是在Form1我如何订阅FileDownloadSucceeded事件:

downloader.FileDownloadSucceeded += new EventHandler(downloader_Succeeded); 

然后在事件

private void downloader_Succeeded(object sender, EventArgs e) 
     { 
      countFilesDownloaded++; 
      label6.Text = countFilesDownloaded.ToString(); 
      RichTextBoxExtensions.UpdateText(richTextBox1, "Ready: ", "Downloaded: ", Color.Green); 
     } 

问题是,当我把一个断点事件中在最后一行RichTextBoxExtensions喜欢它一次到达那里。下载的文件大小为0字节。然后我再次继续在此事件中停止,这次文件的大小已经完全下载或写入。

所以我需要以某种方式检查这个事件,当它完成下载完成。 我该怎么做?

我想在这个事件中对下载的文件进行一些操作,但是我需要确保文件已经下载完毕,并且我现在用一个断点检查,并且只在第二次检测到文件时完成下载/写入硬盘。

更新

我主要在这里的目标是我加入这个方法到Form1

public static Image[] GetFramesFromAnimatedGIF(Image IMG) 
     { 
      List<Image> IMGs = new List<Image>(); 
      int Length = IMG.GetFrameCount(FrameDimension.Time); 

      for (int i = 0; i < Length; i++) 
      { 
       IMG.SelectActiveFrame(FrameDimension.Time, i); 
       IMGs.Add(new Bitmap(IMG)); 
       IMG.Dispose(); 
      } 

      return IMGs.ToArray(); 
     } 

,我想每一个已下载的文件解压/从文件中解析帧的GIF图像的所有文件GIF动画所以在FileDownloadSucceeded事件我前行补充说:

Image img = new Bitmap(downloader.fileName); 

事件

private void downloader_Succeeded(object sender, EventArgs e) 
     { 
      countFilesDownloaded++; 
      label6.Text = countFilesDownloaded.ToString(); 
      RichTextBoxExtensions.UpdateText(richTextBox1, "Ready: ", "Downloaded: ", Color.Green); 
      Image img = new Bitmap(downloader.fileName); 
     } 

在文件名中,我看到:C:\新建文件夹(3)\国家\欧洲\ 07032017_223558 \欧洲--- 07032017_223558384.gif

的文件是存在硬盘上。但我在这条线越来越异常:

Image img = new Bitmap(downloader.fileName); 

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 DownloaderPro.Program.Main() in C:\Users\Chocolade\Documents\Visual Studio 2015\Projects\DownloaderPro\DownloaderPro\DownloaderPro\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=-2147024809 
     Message=Parameter is not valid. 
     Source=System.Drawing 
     StackTrace: 
      at System.Drawing.Bitmap..ctor(String filename) 
      at DownloaderPro.Form1.downloader_Succeeded(Object sender, EventArgs e) in C:\Users\Chocolade\Documents\Visual Studio 2015\Projects\DownloaderPro\DownloaderPro\DownloaderPro\Form1.cs:line 347 
      at DownloaderPro.FileDownloader.bgwDownloader_ProgressChanged(Object sender, ProgressChangedEventArgs e) in C:\Users\Chocolade\Documents\Visual Studio 2015\Projects\DownloaderPro\DownloaderPro\DownloaderPro\FileDownloader.cs:line 549 
      at System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e) 
      at System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg) 
     InnerException: 

这是BackgroundWorker的完整的类:

Class FileDownloader

这是我用winrar的项目:

Project

+1

你可能想看看BackgroundWorker的ReportProgress和OnReportProgress事件。它需要一个ProgressChangedEventArgs,它有一个名为UserState的对象属性,可以传回信息(比如说一个字符串,表示“文件'X'已经完成下载”),所以当WebRequest完成时,引发ReportProgress。 –

回答

1

据我所知,在下载完成后,已经有一个事件发生。

fireEventFromBgw(Event.FileDownloadSucceeded) 

只需在创建背景工作时订阅它即可。

编辑:

你只打了sln文件。在那里看不到太多。 查看FileDownloader.cs的代码后,它看起来像你没有自己写这个“怪物”。

我倒是想提出一个不同的approuch:

WebClient client = new WebClient(); 
client.DownloadFile(source, target); 

其中source为URL和目标路径在哪里下载到。对于简单的照片,它应该做的伎俩。这个approuch是同步的。

之后:

var frames = GetFramesFromAnimatedGIF(new Bitmap(target)); 

多个文件都放在一个循环。

+0

是的,我忘了提及我订阅这个事件已经在Form1中了,我现在用这个部分更新了我的问题,如果你能在这个问题中看到我更新的部分,我现在使用了一个断点,我发现了什么问题,但不知道如何处理它。当它进入事件时,只有在第一次写入文件或第一次完成文件下载时,才会进入FileDownloadSucceeded文件,该文件为9个字节或有时为12kb或其他大小,但仅在第二次文件位于右侧时大小 –

+0

现在我又试了一次,现在每次下载一个文件时它只会进入一次事件,而且文件似乎在硬盘上没有问题,不知道是怎么回事。我会再次更新我的问题,我的主要目标是什么。 –

+0

好的,上次更新我的问题。对不起。现在我正在尝试在事件中做什么以及我得到了什么异常。从一开始,整个问题就是例外。而且有时候它会进入事件并且下载的文件很好完成,但有时我会看到该文件的大小为0字节,并且仅在第二次进入事件时文件没有问题。不知道为什么。但是,如果我不在这个事件中使用断点,并让程序继续工作,那么所有的文件都可以正常工作。所以我想知道这个事件发生了什么?以及如何解决它。 –

相关问题